跳到内容

大语言模型

大语言模型(LLMs)是一种用于文本生成任务的神经网络,例如聊天机器人、代码助手等。与主要设计用于预测任务的 ECD 模型不同,LLMs 是一种本质上生成的模型类型。

LLM 的主干(不含用于下一词元生成的语言模型头部)在使用 auto_transformer 编码器时,可以在 ECD 模型中用作文本编码器。如果您希望将 LLMs 用于分类和回归等预测任务,请尝试 ECD。对于生成任务,请继续阅读!

微调 LLaMA-2-7b 的配置示例

model_type: llm
base_model: meta-llama/Llama-2-7b-hf
input_features:
  - name: input
    type: text
output_features:
  - name: response
    type: text
prompt:
  template: |
    [INST] <<SYS>>
    You are a helpful, detailed, and polite artificial 
    intelligence assistant. Your answers are clear and 
    suitable for a professional environment.
    If context is provided, answer using only the provided 
    contextual information.
    <</SYS>>
    {user_message_1} [/INST]
adapter:
  type: lora
quantization:
  bits: 4
trainer:
  type: finetune
  learning_rate: 0.0001
  batch_size: 1
  gradient_accumulation_steps: 8
  epochs: 3

基础模型

base_model 参数指定用作自定义 LLM 基础的预训练大语言模型。

目前,支持将 HuggingFace Hub 中的任何预训练 HuggingFace 因果语言模型用作 base_model

示例

base_model: meta-llama/Llama-2-7b-hf

注意

HuggingFace Hub 上的一些模型需要执行不受信任的代码。出于安全考虑,目前不支持这些模型。如果您有兴趣使用这些模型中的任何一个,请在 GitHub 上提交一个 issue,说明您的用例。

您也可以传入本地保存的 Hugging Face 模型路径,而不是直接从 Hugging Face 加载。

示例

base_model: path/to/local/model/weights

HuggingFace 访问令牌

一些基础模型,如 Llama-2,需要获得 HuggingFace 的授权才能下载,这进而需要获取 HuggingFace 用户访问令牌

一旦您获得下载首选基础模型的权限并拥有用户访问令牌,您只需确保您的令牌作为环境变量暴露出来,Ludwig 即可使用它。

export HUGGING_FACE_HUB_TOKEN="<api_token>"
ludwig train ...

特征

输入特征

由于 LLMs 的工作方式,它们只接受一个输入,类型为 text。此输入可以由输入数据集的一个或多个列以及可选的穿插静态文本构建。以下三个示例说明了各种可能性。

仅使用单数据集列

如果 intended 使 LLM 的输入仅为单个数据集列的内容(不含任何前缀或后缀文本),则不应提供 prompt 模板,并且特征的 name 必须与该特定数据集列相对应。请参阅以下示例。

input_features:
  - name: input
    type: text

name 属性的值(示例中的 input)是数据集列的名称。

有关配置选项,请参阅文本特征

单数据集列附加文本

如果必须通过在单个数据集列的内容前附加和/或后附加一些静态文本来创建 LLM 的输入,则必须提供 prompt template 来指定如何为 LLM 格式化所选列的内容。请参阅以下示例。

prompt:
  template: |
    Translate into French 
    Input: {english_input}
    Translation:

input_features:
  - name: prompt
    type: text

在上面的示例中,english_input 是输入数据集中的一个列名。在这种情况下,input_featurenameprompt)不是数据集列名(如上一个示例)。它只是一个占位符,通过将模板应用于所选数据集列来替换为格式化文本。实际使用的名称没有特殊意义,因此您可以选择任何在应用程序上下文中直观的名称。

多数据集列穿插静态文本

此情况是将上一个示例推广到必须处理两个或更多数据集列的情形。请参阅下面的示例。

prompt:
  template: |
    [INST] <<SYS>>
    You are a helpful, detailed, and polite AI assistant. 
    Answer the question using only the provided context.
    <</SYS>>

    ### Context:
    {context}

    ### Question:
    {question}

    ### Response:
    [/INST]

input_features:
  - name: prompt
    type: text

如同上一个示例,contextquestion 是输入数据集中的列名。input_featurename(此处为 prompt)同样只是一个占位符,将被应用于所选数据集列后获得的格式化文本替换。使用的名称 (prompt) 没有特殊意义,因此可以使用任何直观的名称而不会改变获得的结果。

输出特征

目前,LLM 模型类型仅支持单个输出特征。

LLM 文本输出特征

微调时 (trainer.type: finetune),输出特征类型必须是 text。即使您正在对 LLM 进行二元或多类别分类问题的微调,也请将该列的输出特征类型设置为 text

对于上下文学习或零样本学习 (trainer.type: none),输出特征类型可以是 textcategory

output_features:
  - name: response
    type: text

有关配置选项,请参阅文本输出特征

LLM 类别输出特征

为了使用 category 输出特征类型,您必须提供两个额外的规范。第一个额外规范是解码器配置中的一组 match 值。这些匹配值用于确定将哪个类别标签分配给生成的响应。这对于缓解 LLM 文本生成偏离所需响应格式的情况特别有帮助。

第二个额外规范是 preprocessing.fallback_label 中的回退标签。此标签既用于填充数据集中输出特征列中的缺失值,也用于在 LLM 无法生成与所提供的任何类别匹配的响应时提供预设值。

output_features:
  - name: label
    type: category
    preprocessing:
      fallback_label: "neutral"
    decoder:
      type: category_extractor
      match:
        "negative":
          type: contains
          value: "negative"
        "neutral":
          type: contains
          value: "neutral"
        "positive":
          type: contains
          value: "positive"

提示词

与更传统的深度学习模型相比,大语言模型的独特特性之一是能够整合插入到“提示词”中的上下文,以生成更具体、更准确的响应。

prompt 参数可用于:

  • 提供必要的模板,使 LLM 以正确的方式响应(例如,回答问题而不是继续输入序列)。
  • 将数据集中的多个列组合成单个文本输入特征(参见 TabLLM)。
  • 为模型提供额外的上下文,帮助其理解任务,或提供限制以防止幻觉。

要使用提示词,必须提供 prompt.templateprompt.task 之一。否则,输入特征值将按原样传递给 LLM。使用 template 可以对提示词的各个方面进行精细控制,而使用 task 可以指定 LLM 要执行的任务性质,同时将确切的提示词模板委托给 Ludwig 的默认设置。

注意

一些已经进行指令微调的模型被训练来期望特定的提示词模板结构。不幸的是,这并未在任何模型元数据中提供,因此您可能需要探索或实验不同的提示词模板,以找到在执行上下文学习时效果最佳的模板。

prompt:
    template: null
    task: null
    retrieval:
        type: null
        index_name: null
        model_name: null
        k: 0
  • template (默认值: null) : 用于提示词的模板。必须包含输入数据集中的至少一个列或 __sample__ 作为由花括号 {} 包围的变量,以指示当前特征的插入位置。可以插入多个列,例如:The {color} {animal} jumped over the {size} {object},其中花括号中的每个术语都是数据集中的一个列。如果指定了 task,则模板还必须包含 __task__ 变量。如果指定了 retrieval,则模板还必须包含 __context__ 变量。如果未提供模板,则将根据检索设置使用默认模板,并且必须在配置中设置 task。
  • task (默认值: null) : 用于提示词的任务。如果未设置 template,则为必填项。
  • retrieval (默认值: {"type": null})

检索

retrieval:
    type: null
    index_name: null
    model_name: null
    k: 0
  • type (默认值: null) : 用于提示词的检索类型。如果为 None,则不使用检索,并将任务视为零样本学习问题。如果不为 None(例如 'random' 或 'semantic'),则从训练集的索引中检索样本,并在小样本学习设置中用于增强模型的输入。
  • index_name (默认值: null): 用于提示词的索引名称。索引默认存储在 ludwig 缓存中。
  • model_name (默认值: null): 用于生成嵌入的模型,这些嵌入用于检索样本并注入提示词。
  • k (默认值: 0): 要检索的样本数量。

最大序列长度

在单 GPU 上高效微调 LLMs 时,有许多因素起作用

在控制 GPU 内存使用方面,最重要的参数之一是选择最大序列长度。

Ludwig 提供了 3 个主要参数来控制最大序列长度:

  1. 输入示例上的 input_feature.preprocessing.max_sequence_length,它包含您的提示词。
  2. 输出示例上的 output_feature.preprocessing.max_sequence_length,它不包含您的提示词。
  3. preprocessing.global_max_sequence_length,这是在训练期间馈送到 LLM 前向传播的最大长度序列(合并输入和输出)。

img

如果您遇到 GPU 内存不足 (OOM) 问题,请考虑分析您的数据集以了解序列长度的分布。对于具有长尾分布的输入/输出列,可能值得考虑选择较小的最大序列长度,以便截断少量数据,同时仍可以使用较小的 GPU 进行训练。

适配器

LLMs 高效微调的最大障碍之一是每个训练步骤需要更新数十亿个参数。参数高效微调 (PEFT) 适配器是一系列技术,它们减少了微调期间可训练参数的数量,从而加快了训练速度,并减少了训练大型语言模型所需的内存和磁盘空间。

PEFT 是 HuggingFace 的一个流行库,它实现了许多流行的参数高效微调策略。Ludwig 与 PEFT 提供了原生集成,允许您通过 adapter 配置参数利用多种技术更有效地微调 LLMs。

LoRA

LoRA 是一种简单而有效的预训练语言模型参数高效微调方法。它通过向模型添加少量可训练参数来实现,这些参数用于使预训练参数适应下游任务。这使得模型可以使用少得多的训练样本进行微调,甚至可以用于在根本没有训练数据的任务上对模型进行微调。

adapter:
    type: lora
    r: 8
    dropout: 0.05
    target_modules: null
    use_rslora: false
    use_dora: false
    alpha: 16
    pretrained_adapter_weights: null
    postprocessor:
        merge_adapter_into_base_model: false
        progressbar: false
    bias_type: none
  • r (默认值: 8) : Lora 注意力维度。
  • dropout (默认值: 0.05): Lora 层的 dropout 概率。
  • target_modules (默认值: null): 要用 LoRA 替换的模块名称列表或模块名称的正则表达式。例如 ['q', 'v'] 或 '.decoder.(SelfAttention|EncDecAttention).*(q|v)$'。默认为定位所有自注意力和编码器-解码器注意力层的查询和值矩阵。
  • use_rslora (默认值: false): 设置为 True 时,使用 Rank-Stabilized LoRA,它将适配器缩放因子设置为 lora_alpha/math.sqrt(r),因为它已被证明效果更好。否则,它将使用原始默认值 lora_alpha/r。论文:https://arxiv.org/abs/2312.03732。选项:true, false
  • use_dora (默认值: false): 启用“权重分解低秩适应”(DoRA)。这项技术将权重的更新分解为两部分:幅度和方向。方向由普通的 LoRA 处理,而幅度由一个单独的可学习参数处理。这可以提高 LoRA 的性能,尤其是在低秩情况下。目前,DoRA 仅支持非量化线性层。DoRA 引入的开销比纯粹的 LoRA 更大,因此建议在推理时合并权重。更多信息,请参阅 https://arxiv.org/abs/2402.09353 选项:true, false
  • alpha (默认值: null): Lora 缩放的 alpha 参数。默认为 2 * r
  • pretrained_adapter_weights (默认值: null): 预训练权重的路径。
  • 后处理器 :
  • postprocessor.merge_adapter_into_base_model (默认值: false): 指示是否将微调后的 LoRA 权重合并到基础 LLM 模型中,以便完整微调后的模型可供使用和/或持久化,然后在加载时作为单个模型重复使用(而不是必须单独加载基础模型和微调模型)。选项:true, false
  • postprocessor.progressbar (默认值: false): 指示是否显示一个进度条,指示卸载和合并过程。选项:true, false
  • bias_type (默认值: none): Lora 的偏差类型。选项:none, all, lora_only

AdaLoRA

AdaLoRA 是 LoRA 的一个扩展,它允许模型以任务特定的方式使预训练参数适应下游任务。这通过向模型添加少量可训练参数来实现,这些参数用于使预训练参数适应下游任务。这使得模型可以使用少得多的训练样本进行微调,甚至可以用于在根本没有训练数据的任务上对模型进行微调。

adapter:
    type: adalora
    r: 8
    dropout: 0.05
    target_modules: null
    use_rslora: false
    use_dora: false
    alpha: 16
    pretrained_adapter_weights: null
    postprocessor:
        merge_adapter_into_base_model: false
        progressbar: false
    bias_type: none
    target_r: 8
    init_r: 12
    tinit: 0
    tfinal: 0
    delta_t: 1
    beta1: 0.85
    beta2: 0.85
    orth_reg_weight: 0.5
    total_step: null
    rank_pattern: null
  • r (默认值: 8) : Lora 注意力维度。
  • dropout (默认值: 0.05): Lora 层的 dropout 概率。
  • target_modules (默认值: null): 要用 LoRA 替换的模块名称列表或模块名称的正则表达式。例如 ['q', 'v'] 或 '.decoder.(SelfAttention|EncDecAttention).*(q|v)$'。默认为定位所有自注意力和编码器-解码器注意力层的查询和值矩阵。
  • use_rslora (默认值: false): 设置为 True 时,使用 Rank-Stabilized LoRA,它将适配器缩放因子设置为 lora_alpha/math.sqrt(r),因为它已被证明效果更好。否则,它将使用原始默认值 lora_alpha/r。论文:https://arxiv.org/abs/2312.03732。选项:true, false
  • use_dora (默认值: false): 启用“权重分解低秩适应”(DoRA)。这项技术将权重的更新分解为两部分:幅度和方向。方向由普通的 LoRA 处理,而幅度由一个单独的可学习参数处理。这可以提高 LoRA 的性能,尤其是在低秩情况下。目前,DoRA 仅支持非量化线性层。DoRA 引入的开销比纯粹的 LoRA 更大,因此建议在推理时合并权重。更多信息,请参阅 https://arxiv.org/abs/2402.09353 选项:true, false
  • alpha (默认值: null): Lora 缩放的 alpha 参数。默认为 2 * r
  • pretrained_adapter_weights (默认值: null): 预训练权重的路径。
  • 后处理器 :
  • postprocessor.merge_adapter_into_base_model (默认值: false): 指示是否将微调后的 LoRA 权重合并到基础 LLM 模型中,以便完整微调后的模型可供使用和/或持久化,然后在加载时作为单个模型重复使用(而不是必须单独加载基础模型和微调模型)。选项:true, false
  • postprocessor.progressbar (默认值: false): 指示是否显示一个进度条,指示卸载和合并过程。选项:true, false
  • bias_type (默认值: none): Lora 的偏差类型。选项:none, all, lora_only
  • target_r (默认值: 8): 目标 Lora 矩阵维度。增量矩阵的目标平均秩。
  • init_r (默认值: 12): 初始 Lora 矩阵维度。每个增量矩阵的初始秩。
  • tinit (默认值: 0): 初始微调热身的步数。
  • tfinal (默认值: 0): 最终微调热身的步数。
  • delta_t (默认值: 1): 两次预算分配之间的时间间隔。秩分配的步长间隔。
  • beta1 (默认值: 0.85): 用于敏感度平滑的 EMA 超参数。
  • beta2 (默认值: 0.85): 用于不确定性量化的 EMA 超参数。
  • orth_reg_weight (默认值: 0.5): 正交正则化系数。
  • total_step (默认值: null): 训练前应指定的总训练步数。
  • rank_pattern (默认值: null): 由 RankAllocator 为每个权重矩阵分配的秩。

IA3

通过抑制和放大内部激活注入适配器(Infused Adapter by Inhibiting and Amplifying Inner Activations),或 IA3,是一种添加三个学习向量 l_k``,l_v`, 和l_ff` 的方法,分别用于重新缩放自注意力层和编码器-解码器注意力层的键和值,以及位置前馈网络的中间激活。这些学习向量是微调期间唯一可训练的参数,因此原始权重保持冻结。处理学习向量(而不是像 LoRA 那样对权重矩阵进行学习的低秩更新)使可训练参数的数量大大减少。

adapter:
    type: ia3
    target_modules: null
    feedforward_modules: null
    fan_in_fan_out: false
    modules_to_save: null
    init_ia3_weights: true
    pretrained_adapter_weights: null
    postprocessor:
        merge_adapter_into_base_model: false
        progressbar: false
  • target_modules (默认值: null) : 要应用 (IA)^3 的模块名称。
  • feedforward_modules (默认值: null) : 根据原始论文,要被视为前馈模块的模块名称。这些模块将对输入乘以 (IA)^3 向量,而不是对输出。feedforward_modules 必须是 target_modules 中存在的名称或名称的子集。
  • fan_in_fan_out (默认值: false) : 如果要替换的层存储的权重形式为 (fan_in, fan_out),则将其设置为 True。例如,gpt-2 使用 Conv1D,其权重存储形式为 (fan_in, fan_out),因此应将其设置为 True。选项:true, false
  • modules_to_save (默认值: null) : 除 (IA)^3 层外,设置为可训练并保存在最终检查点中的模块列表。
  • init_ia3_weights (默认值: true) : 是否初始化 (IA)^3 层中的向量,默认为 True。选项:true, false
  • pretrained_adapter_weights (默认值: null): 预训练权重的路径。
  • 后处理器 :
  • postprocessor.merge_adapter_into_base_model (默认值: false): 指示是否将微调后的 LoRA 权重合并到基础 LLM 模型中,以便完整微调后的模型可供使用和/或持久化,然后在加载时作为单个模型重复使用(而不是必须单独加载基础模型和微调模型)。选项:true, false
  • postprocessor.progressbar (默认值: false): 指示是否显示一个进度条,指示卸载和合并过程。选项:true, false

量化

量化允许您将模型参数(通常存储为 16 位或 32 位浮点数)加载为 4 位或 8 位整数。这使您可以将 GPU 内存开销降低多达 8 倍。

当与 LoRA 适配器结合使用时,您可以按照论文 QLoRA 中所述执行量化微调。这使得在单块通用 GPU 上训练高达 70 亿参数的大型语言模型成为可能,且性能损失最小。

注意

量化微调目前需要使用 adapter: lora。上下文学习没有此限制。

注意

目前仅在使用 backend: local 时支持量化。

quantization:
    bits: 4
    llm_int8_threshold: 6.0
    llm_int8_has_fp16_weight: false
    bnb_4bit_compute_dtype: float16
    bnb_4bit_use_double_quant: true
    bnb_4bit_quant_type: nf4
  • bits (默认值: 4) : 加载时应用于权重的量化级别。选项:4, 8
  • llm_int8_threshold (默认值: 6.0): 这对应于论文 LLM.int8() : 8-bit Matrix Multiplication for Transformers at Scale 中描述的用于离群点检测的离群点阈值:https://arxiv.org/abs/2208.07339。任何高于此阈值的隐藏状态值将被视为离群点,并且对这些值的操作将在 fp16 中完成。值通常呈正态分布,即大多数值在 [-3.5, 3.5] 范围内,但对于大型模型,存在一些分布非常不同的特殊系统性离群点。这些离群点通常在 [-60, -6] 或 [6, 60] 区间内。Int8 量化对于幅度约为 5 的值效果很好,但超出此范围,性能会显著下降。一个好的默认阈值是 6,但对于更不稳定的模型(小型模型、微调)可能需要较低的阈值。
  • llm_int8_has_fp16_weight (默认值: false): 此标志使用 16 位主权重运行 LLM.int8()。这对于微调很有用,因为无需在反向传播时来回转换权重。选项:true, false
  • bnb_4bit_compute_dtype (默认值: float16): 这设置了计算类型,该类型可能与输入类型不同。例如,输入可以是 fp32,但计算可以设置为 bf16 以提高速度。选项:float32, float16, bfloat16
  • bnb_4bit_use_double_quant (默认值: true): 此标志用于嵌套量化,其中第一次量化的量化常数会再次被量化。选项:true, false
  • bnb_4bit_quant_type (默认值: nf4): 这设置了 bnb.nn.Linear4Bit 层中的量化数据类型。选项:fp4, nf4

模型参数

模型参数部分用于在模型初始化期间自定义 LLM 模型参数。目前,唯一支持的初始化参数是 rope_scaling

# Defaults
model_parameters:
  rope_scaling: {}
  neftune_noise_alpha: 0

RoPE 缩放

像 LLaMA-2 这样的大语言模型在考虑上下文的长度方面面临限制,这影响了它们理解跨多个段落的复杂查询或聊天式讨论的能力。例如,LLaMA-2 的上下文长度上限为 4096 个词元,大约相当于 3000 个英文单词。这使得该模型对于涉及超过此上下文长度的长文档的任务效率低下。

RoPE 缩放提出了一种通过称为位置插值的方法增加模型上下文长度的方式,但会牺牲轻微的性能。您可以在原始论文此处阅读更多信息。

对于 RoPE 缩放,有两个参数需要考虑:typefactor。通常的经验法则是,您的新上下文长度将是 context_length * factor。因此,如果您想将 LLaMA-2 扩展到拥有约 16K 词元的上下文长度,您将把 factor 设置为 4.0。type 属性支持 linear 插值和 dynamic 插值。通常,在更大的上下文长度下,dynamic 插值具有最佳性能,同时保持较低的困惑度。

图片致谢 Reddit 用户 /u/emozilla 和 /u/kaiokendev 的工作以及此图。

您可以使用以下配置在 Ludwig 中启用 RoPE 缩放:

rope_scaling:
    type: dynamic
    factor: 2.0
  • type (默认值: null): 当前支持两种策略:线性缩放和动态缩放。选项:linear, dynamic, null
  • factor (默认值: null): RoPE 嵌入的缩放因子。

注意

通常,您需要启用 RoPE 缩放对 LLM 进行约 1000 步的微调,以确保 RoPE 缩放带来的性能下降最小,并且模型将您的数据适应新的 RoPE 嵌入。

Neftune 噪声 Alpha

NEFTune 是一种在微调期间提升模型性能的技术。NEFTune 在训练期间向嵌入向量添加噪声。alpha 参数用作控制机制,允许用户调节引入到嵌入中的噪声强度。较高的 alpha 值对应于更多的噪声,影响微调阶段的嵌入向量。

使用 Alpaca 对 LLaMA-2-7B 进行标准微调在 AlpacaEval 上达到了 29.79% 的性能,而使用噪声嵌入则提高到 64.69%。NEFTune 在现代指令数据集上的表现也优于强大的基线。您可以在题为“NEFTune: Noisy Embeddings Improve Instruction Finetuning”的论文中找到更多信息。

您可以使用以下配置在 Ludwig 中启用 NEFTune:

model_parameters:
  neftune_noise_alpha: 5

训练器

LLMs 支持多种不同的训练目标:

  • 微调 (type: finetune): 使用监督学习更新预训练 LLM 的权重。
  • 上下文学习 (type: none): 仅使用提示词中提供的上下文评估模型性能并进行预测。

微调

有关微调的配置选项,请参阅训练器部分。

trainer:
  type: finetune

上下文学习

对于上下文学习,指定 none 训练器表示不会更新模型参数,“训练”步骤基本上是一个空操作,仅用于计算测试集上的评估指标。

trainer:
  type: none

生成

使用预训练或微调的 LLM 进行推理生成文本时,您可能经常希望控制生成过程,例如使用何种词元解码策略、生成多少新词元、排除哪些词元,或者希望生成文本有多样化。所有这些都可以通过 Ludwig 中的 generation 配置进行控制。

尽管 Ludwig 为其中大多数参数设置了预定义的默认值,但一些最常用于控制生成过程的参数是:

  • max_new_tokens
  • temperature
  • do_sample
  • num_beams
  • top_k
  • top_p

查看以下参数的描述!

generation:
    max_new_tokens: 32
    temperature: 0.1
    min_new_tokens: null
    max_length: 32
    min_length: 0
    do_sample: true
    num_beams: 1
    use_cache: true
    prompt_lookup_num_tokens: null
    top_k: 50
    top_p: 1.0
    early_stopping: false
    max_time: null
    num_beam_groups: 1
    penalty_alpha: null
    typical_p: 1.0
    epsilon_cutoff: 0.0
    eta_cutoff: 0.0
    diversity_penalty: 0.0
    repetition_penalty: 1.0
    encoder_repetition_penalty: 1.0
    length_penalty: 1.0
    no_repeat_ngram_size: 0
    bad_words_ids: null
    force_words_ids: null
    renormalize_logits: false
    forced_bos_token_id: null
    forced_eos_token_id: null
    remove_invalid_values: false
    exponential_decay_length_penalty: null
    suppress_tokens: null
    begin_suppress_tokens: null
    forced_decoder_ids: null
    sequence_bias: null
    guidance_scale: null
    pad_token_id: null
    bos_token_id: null
    eos_token_id: null
  • max_new_tokens (默认值: 32) : 要生成的新词元的最大数量,忽略输入提示词中的词元数量。如果未设置,Ludwig 将根据输出特征的 max_sequence_length、预处理中指定的 global_max_sequence_length(如果指定)或模型支持的最大上下文长度(按指定顺序)动态确定此值。
  • temperature (默认值: 0.1) : 温度用于控制预测的随机性。较高的温度值(接近 1)会使输出更加多样化和随机,而较低的温度值(接近 0)会使模型的响应更加确定并倾向于最可能的结果。换句话说,温度调整了模型选择下一个词元的概率分布。
  • min_new_tokens (默认值: null): 要生成的新词元的最小数量,忽略输入提示词中的词元数量。
  • max_length (默认值: 32): 生成词元的总长度上限。对应于输入提示词的长度 + max_new_tokens。如果也设置了 max_new_tokens,则其效果会被覆盖。
  • min_length (默认值: 0): 要生成的序列的总长度下限。对应于输入提示词的长度 + min_new_tokens。如果也设置了 min_new_tokens,则其效果会被覆盖。
  • do_sample (默认值: true): 是否使用采样;否则使用贪婪解码。选项:true, false
  • num_beams (默认值: 1): 集束搜索的集束数量。1 表示不使用集束搜索,是默认值。集束搜索策略在词元生成期间,在每个时间步 t 保留固定数量 (num_beams) 的活动候选序列,并最终选择整体概率最高的序列。通过增加集束大小,可以提高翻译性能,但会显著降低解码速度。
  • use_cache (默认值: true): 模型是否应该使用过去的最后键/值注意力(如果适用于模型)来加速解码。选项:true, false
  • prompt_lookup_num_tokens (默认值: null): 从提示词中考虑作为提示词查找解码候选词元的数量,这是一种执行辅助生成的替代方法。如果设置为 0,则不使用提示词查找解码。
  • top_k (默认值: 50): 用于 top-k 过滤的最高概率词汇词元数量。
  • top_p (默认值: 1.0): 如果设置为小于 1 的浮点数,则只保留概率加起来达到 top_p 或更高的最可能的词元进行生成。
  • early_stopping (默认值: false): 控制基于集束的方法(如集束搜索)的停止条件。它接受以下值:True,一旦有 num_beams 个完整候选序列生成完成即停止生成;False,应用启发式方法,当极不可能找到更好的候选序列时停止生成;never,集束搜索过程仅在无法找到更好的候选序列时停止(标准集束搜索算法)选项:true, false
  • max_time (默认值: null): 您允许计算运行的最长时间(秒)。生成将在分配的时间过后完成当前处理。
  • num_beam_groups (默认值: 1): 将 num_beams 分成的组数,以确保不同集束组之间的多样性。1 表示不使用分组集束搜索。
  • penalty_alpha (默认值: null): 在对比搜索解码中平衡模型置信度和退化惩罚的值。
  • typical_p (默认值: 1.0): 局部典型性衡量预测下一个目标词元的条件概率与给定已生成部分文本预测下一个随机词元的预期条件概率的相似程度。如果设置为小于 1 的浮点数,则保留概率加起来达到 typical_p 或更高的局部典型性最高的最小词元集进行生成。
  • epsilon_cutoff (默认值: 0.0): 如果设置为严格介于 0 和 1 之间的浮点数,则仅对条件概率大于 epsilon_cutoff 的词元进行采样。在论文中,建议的值范围为 3e-4 到 9e-4,具体取决于模型的大小。
  • eta_cutoff (默认值: 0.0): Eta 采样是局部典型性采样和 epsilon 采样的一种混合。如果设置为严格介于 0 和 1 之间的浮点数,则只有当词元的条件概率大于 eta_cutoff 或 sqrt(eta_cutoff) * exp(-entropy(softmax(next_token_logits))) 时才会被考虑。后一项直观上是预期下一个词元概率,并按 sqrt(eta_cutoff) 进行缩放。在论文中,建议的值范围为 3e-4 到 2e-3,具体取决于模型的大小。
  • diversity_penalty (默认值: 0.0): 用于控制生成文本多样性的值。值越高,文本越多样化。如果设置为 0,则不强制多样性。如果某个集束在特定时间生成了与来自其他组的任何集束相同的词元,则从该集束的分数中减去此值。请注意,diversity_penalty 仅在启用分组集束搜索时有效。
  • repetition_penalty (默认值: 1.0): 重复惩罚参数。1.0 表示没有惩罚。更多详情请参阅这篇论文
  • encoder_repetition_penalty (默认值: 1.0): 编码器重复惩罚参数。对不在原始输入中的序列施加指数惩罚。1.0 表示没有惩罚。
  • length_penalty (默认值: 1.0): 用于基于集束生成方法的长度指数惩罚。它作为序列长度的指数应用,进而用于除以序列的分数。由于分数是序列的对数似然(即负值),length_penalty > 0.0 促进生成较长序列,而 length_penalty < 0.0 鼓励生成较短序列。
  • no_repeat_ngram_size (默认值: 0): 如果设置为大于 0 的整数,则该大小的所有 n-gram 只能出现一次。
  • bad_words_ids (默认值: null): 不允许生成的词元 ID 列表。为了获取不应出现在生成文本中的词元的 ID,请使用 tokenizer(bad_word, add_prefix_space=True).input_ids。
  • force_words_ids (默认值: null): 模型强制生成的词元 ID 列表。为了获取应出现在生成文本中的词元的 ID,请使用 tokenizer(force_word, add_prefix_space=True).input_ids。
  • renormalize_logits (默认值: false): 是否在温度和 top_k/top_p 过滤后重新归一化 logits。选项:true, false
  • forced_bos_token_id (默认值: null): 在 decoder_start_token_id 之后强制作为第一个生成词元的 ID。这对于像 mBART 这样的多语言模型很有用,其中第一个生成词元需要是目标语言词元。
  • forced_eos_token_id (默认值: null): 当达到 max_length 时强制作为最后一个生成词元的 ID。可选地,使用列表设置多个序列结束词元。
  • remove_invalid_values (默认值: false): 是否移除模型可能的 nan 和 inf 输出,以防止生成方法崩溃。请注意,使用 remove_invalid_values 可能会减慢生成速度。选项:true, false
  • exponential_decay_length_penalty (默认值: null): 此元组在生成一定数量的词元后,添加指数级增加的长度惩罚。元组应包含:(start_index, decay_factor),其中 start_index 表示惩罚开始的位置,decay_factor 表示指数衰减的因子。
  • suppress_tokens (default: null): 在生成时将被抑制的词元列表。SupressTokens logit 处理器会将它们的 log 概率设置为 -inf,以便不会被采样。
  • begin_suppress_tokens (default: null): 在生成开始时将被抑制的词元列表。SupressBeginTokens logit 处理器会将它们的 log 概率设置为 -inf,以便不会被采样。
  • forced_decoder_ids (default: null): 强制解码器 ID 列表。ForcedDecoderIds logit 处理器会将不在列表中的所有词元的 log 概率设置为 -inf,以便不会被采样。
  • sequence_bias (默认值: null): 一个词元 ID 字典,用于偏向生成。SequenceBias logit 处理器会将偏差添加到字典中词元的 log 概率中。正偏差会增加序列被选中的可能性,而负偏差则相反。
  • guidance_scale (默认值: null): 分类器无关指导 (CFG) 的指导比例。通过设置 guidance_scale > 1 启用 CFG。较高的指导比例鼓励模型生成与输入提示词更紧密相关的样本,但这通常会牺牲质量。
  • pad_token_id (默认值: null): 填充词元的 ID。如果未设置,则使用分词器的填充词元 ID。
  • bos_token_id (默认值: null): 句子开头词元的 ID。如果未设置,则使用分词器的 bos 词元 ID。
  • eos_token_id (默认值: null): 句子结束词元的 ID。如果未设置,则使用分词器的 eos 词元 ID。

生成策略

文本生成可以通过多种方式进行推理。大体上,有 5 种策略:

  • 贪婪解码(默认): 贪婪搜索是最简单的解码方法。它在每个时间步 t 选择概率最高的词作为下一个词。
  • 集束搜索: 集束搜索通过在每个时间步 t 保留最有可能的 num_beams 个假设,并最终选择整体概率最高的假设,从而降低错过隐藏的高概率词序列的风险。
  • 采样: 采样意味着根据其条件概率分布随机选择下一个词。使用采样进行语言生成不是确定性的。
  • Top-k 采样: 在 Top-k 采样中,过滤掉最可能的 k 个下一个词,并且概率质量仅在这些 k 个下一个词之间重新分配。
  • Top-p(核)采样: Top-p 采样不是仅从最可能的 K 个词中采样,而是从累积概率超过概率 p 的最小可能词汇集合中选择。然后,概率质量在此词汇集合中重新分配。这样,词汇集合的大小(也称为集合中的词数)可以根据下一个词的概率分布动态增加或减少。

如果您想启用除贪婪解码之外的其他解码策略,可以在生成配置中设置以下参数来启用它们。

  • 贪婪解码(默认):
generation:
  num_beams: 1
  do_sample: false
  • 多项式采样:
generation:
  num_beams: 1
  do_sample: true
  • 集束搜索解码:
generation:
  num_beams: 2 # Must be > 1
  do_sample: false
  • 对比搜索:
generation:
  penalty_alpha: 0.1 # Must be > 0
  top_k: 2 # Must be > 1
  • 集束搜索多项式采样:
generation:
  num_beams: 2 # Must be > 1
  do_sample: true
  • 多样化集束搜索解码:
generation:
  num_beams: 2 # Must be > 1
  num_beam_groups: 2 # Must be > 1

要以可视化方式了解这些解码策略的工作原理,请查看 HuggingFace 撰写的这篇精彩博客文章。

微调后处理

上传微调后的 LLM 权重到 HuggingFace Hub

微调模型后,您可以将微调后的模型 Artifact 直接上传到 HuggingFace Hub,可以上传到任何人都可以访问的公共模型仓库,也可以上传到私有仓库。这适用于完整微调以及基于适配器的微调生成的 Artifact。然后,您可以将权重直接拉取到下游推理服务中,甚至可以直接通过 Ludwig 用于推理。

ludwig upload hf_hub --repo_id <repo_id> --model_path </path/to/saved/model>

要了解更多关于如何执行此操作的信息,请点击此处