Jiahong 的个人博客

凡事预则立,不预则废


  • Home

  • Tags

  • Archives

  • Navigation

  • Search

NLP——基于vLLM的RAG服务部署

  • 参考连接:
    • 实操用Langchain,vLLM,FastAPI构建一个自托管的Qwen-7B-Chat - FunHPC的文章 - 知乎

系统说明和环境安装

系统说明

  • 本文采用 Ubuntu 22.04 LTS

Python基础环境准备

  • 包括 anaconda, python 等环境安装

创建虚拟环境

  • conda创建python环境
    1
    conda create -n llm_py310 python==3.10

安装相关包

  • 安装下面的依赖项

    1
    2
    3
    pip install pytorch langchain vllm gptcache modelscope
    pip install transformers accelerate tiktoken einops scipy transformers_stream_generator==0.0.4 peft deepspeed
    `
    • 如果出错建议一个个安装

huggingface命令行工具安装

  • 安装工具
    1
    git lfs install

下载模型到本地(可跳过)

  • 使用 git 命令下载 huggingface 项目(方便从本地启动)

    1
    git clone https://huggingface.co/Qwen/Qwen3-0.6B
  • 推荐使用 modelscope,这样不需要科学上网

    1
    2
    3
    pip install modelscope
    modelscope download --model Qwen/Qwen3-0.6B # 缓存到本地 ~/.cache/modelscope/hub/models/Qwen/Qwen3-0.6B/ 目录下
    modelscope download --model Qwen/Qwen3-0.6B --local_dir ./Qwen3-0.6B/ # 保存到 ./Qwen3-0.6B/ 目录下

生成检索 embedding

  • 这里可能遇到一些问题:
    • modelscope 版本问题,遇到相关报错时改用 1.15.0 版本解决
    • 可能需要安装 langchain_community

加载模型时显存爆炸问题

  • 显存可能爆炸(即使加载很小的模型,亲测24G显存会被 Qwen3-0.6B直接占满)
  • 加载模型会默认将整个GPU 所有显存都占用(原因未知)
  • 解决方案:
    • 可以增加 gpu_memory_utilization=0.8 来指定模型的显存使用,也可以根据需要使用其他值,比如0.7,但需要满足最低使用要求
  • 注:除模型参数外的其他显存占用要求
    • 模型需要提前分配 KV Cache,且该值与max_model_len有关,且默认使用比较大的值(比如 max_model_len=40960,导致需要提前分配较大的 KV Cache,从而增加显存)

Bug 记录

  • 遇到 AttributeError: 'State' object has no attribute 'engine_client'
  • 问题详情见:[Bugfix] Fix AttributeError: ‘State’ object has no attribute ‘engine_client’
  • 使用 vllm==0.9.0 及以上或者降低到 vllm==0.8.0 (降低到 0.8.0 亲测有效)

附录:vLLM 使用代码示例

  • 以下是一个简单的 vLLM 使用示例,展示了如何使用 vLLM 加载模型并生成文本:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    from vllm import LLM, SamplingParams

    model_name = "llama-2-7b-chat-hf"
    llm = LLM(model=model_name)
    sampling_params = SamplingParams(
    temperature=0.7,
    top_p=0.95,
    max_tokens=1024
    )
    prompts = [
    "介绍一下人工智能的发展历程",
    "解释一下量子计算的基本原理",
    "推荐几部好看的科幻电影"
    ]

    outputs = llm.generate(prompts, sampling_params)

    for output in outputs:
    prompt = output.prompt
    generated_text = output.outputs[0].text
    print(f"提示: {prompt}")
    print(f"生成内容: {generated_text}")
    print("-" * 80)

NLP——技术报告解读-Llama3

注:本文包含 AI 辅助创作

  • 参考链接:
    • 原始论文:The Llama 3 Herd of Models, 20240723, Llama Team, Meta AI

Paper Summary

  • 评价:Llama3 作为 24 年最成功的开原模型,是非常值得敬佩的,Meta 为开源社区做的贡献值得永远铭记
  • 论文介绍了一组原生支持多语言、编码、推理和工具使用的语言模型(Llama 3)
  • 论文发布的最大的模型是具有 405B 参数的 Dense Transformer,上下文窗口可达 128K tokens
  • 论文对 Llama 3 进行了广泛的实证评估,发现 Llama 3 在众多任务上的质量可与GPT-4等领先语言模型相媲美
  • 论文公开发布了 Llama 3,包括 405B 参数语言模型的预训练和后训练版本,以及用于输入和输出安全的 Llama Guard 3 模型
  • 论文还介绍了通过组合方法将图像、视频和语音能力集成到 Llama 3 中的实验结果
  • 论文观察到,这种方法在图像、视频和语音识别任务上与最先进水平具有竞争力
    • 由此产生的模型尚未广泛发布,因为它们仍在开发中
    • 注:图像和视觉模型在后续的 Llama 3.2 Vision 11B 等模型中发布
  • 特别说明:论文中实验所说的模型都是 Llama 3.1 模型,论文将其简称为 Llama 3

Introduction and Discussion

  • 基础模型是语言、视觉、语音和其他模态的通用模型,旨在支持各种 AI 任务。它们构成了许多现代AI系统的基础(2023)
  • 现代基础模型的开发包括两个主要阶段:
    • (1)预训练阶段,使用简单任务(如预测下一个词或生成字幕)对模型进行大规模训练;
    • (2)后训练阶段,对模型进行微调以遵循指令、与人类偏好保持一致,并提升特定能力(如编码和推理)(2023)
  • 在论文中,论文介绍了一组新的语言基础模型,称为 Llama 3
    • Llama 3 系列模型原生支持多语言、编码、推理和工具使用
    • 论文最大的模型是一个具有 405B 参数的 Dense Transformer,可在高达 128K tokens的上下文窗口中处理信息
  • 该系列的每个模型如表1 所示。为简洁起见,论文中呈现的所有结果均针对 Llama 3.1 模型,在全文中论文将其简称为 Llama 3
  • 作者认为,开发高质量基础模型有三个关键因素 :数据、规模和复杂性管理(data, scale, and managing complexity) ,论文在开发过程中力求对这三个因素进行优化:
    • 数据 :与之前的Llama版本(2023a,b)相比,论文改进了用于预训练和后训练的数据的数量和质量,这些改进包括:
      • 为预训练数据开发更精细的预处理和精选 Pipeline
      • 以及为后训练数据开发更严格的质量保证和过滤方法
      • 论文在约 15T 多语言 tokens 的语料库上预训练 Llama 3(注:Llama 2 的预训练 tokens 为 1.8T)
    • 规模 :论文训练的模型规模远大于之前的 Llama 模型:
      • 论文的旗舰(flagship)语言模型使用 \(3.8×10^{25}\) 次浮点运算(FLOPs)进行预训练,几乎是最大版本 Llama 2 的 50倍 以上
      • 具体而言,论文在 15.6T 文本 tokens 上预训练了一个具有 405B 可训练参数的旗舰模型
      • 正如基础模型的 Scaling Laws 所预期的那样,论文的旗舰模型优于使用相同流程训练的较小模型
      • 尽管 Scaling Laws 表明,对于论文的训练预算,旗舰模型的大小接近计算最优(compute-optimal),但论文对较小模型的训练时间远超过计算最优所需的时间
        • 由此产生的模型在相同推理预算下的性能优于计算最优的模型
      • 在后训练期间,论文使用旗舰模型进一步提高这些较小模型的质量
    • 复杂性管理 :论文做出的设计选择旨在最大化模型开发过程的扩展能力
      • 例如,论文选择了具有微小调整的标准 Dense Transformer 模型架构(2017),而不是 MoE 模型(2017),以最大化训练稳定性
      • 同样,论文采用了相对简单的后训练程序,基于 SFT 、拒绝采样(RS)和直接偏好优化(DPO;2023),而不是更复杂的强化学习算法(2022; 2017),因为后者往往稳定性较差且更难扩展
  • 论文的工作成果是 Llama 3:
    • 一组具有 8B 、70B 和 405B 参数的三种多语言模型
    • 论文在涵盖广泛语言理解任务的众多基准数据集上评估了 Llama 3 的性能
    • 论文还进行了广泛的人类评估,将 Llama 3 与竞争模型进行比较
  • 旗舰 Llama 3 模型在关键基准上的性能概述如表2 所示
    • 论文的实验评估表明,论文的旗舰模型在各种任务上的表现与 GPT-4(2023a)等领先语言模型相当,且接近最先进水平
    • 论文的较小模型在同类模型中表现最佳,优于具有相似参数数量的替代模型(2023; 2023)
    • 与前身相比, Llama 3 在有用性和无害性之间取得了更好的平衡(2023b)
    • 论文在第5.4节 中对 Llama 3 的安全性进行了详细分析
  • 论文根据更新后的 Llama 3 社区许可证公开发布了所有三个 Llama 3 模型;(详情请参见 https://llama.meta.com)
    • 这包括 405B 参数语言模型的预训练和后训练版本,以及新版本的 Llama Guard 模型(2023)(用于输入和输出安全)
    • 作者希望旗舰模型的开放发布将推动研究社区的创新浪潮,并加速通往通用人工智能(AGI)的负责任发展道路
  • 作为 Llama 3 开发过程的一部分,论文还开发了模型的多模态扩展,通过组合方法实现图像识别、视频识别和语音理解能力
    • 这些模型仍在积极开发中,尚未准备好发布
    • 除了语言建模结果外,论文还介绍了论文对这些多模态模型的初步实验结果

General Overview

  • Llama 3 的模型架构如图1 所示
  • Llama 3 语言模型的开发包括两个主要阶段:
    • 语言模型预训练 :论文首先将大型多语言文本语料库转换为离散 tokens,并在生成的数据上预训练 LLM ,以执行 Next-Token Prediction 任务
      • 在语言模型预训练阶段,模型学习语言结构,并从所“阅读(reading)”的文本中获取大量关于世界的知识
      • 为了有效地做到这一点,预训练是在大规模上进行的:论文在 15.6T tokens 上使用 8K tokens 的上下文窗口预训练了一个具有 405B 参数的模型
      • 这个标准预训练阶段之后是持续预训练阶段 ,将支持的上下文窗口增加到 128K tokens(详情见第3节)
    • 语言模型后训练 :预训练的语言模型对语言有深入的理解,但尚未遵循指令或表现出论文期望助手具备的行为
      • 论文通过多轮人类反馈使模型保持一致,每轮都涉及对指令调整数据进行 SFT 和直接偏好优化(DPO;2024)
      • 在后训练阶段,论文还集成新功能,如工具使用,并观察到其他领域的显著改进,如编码和推理(详情见第4节)
      • 最后,在后训练阶段,模型还融入了安全缓解措施(具体细节在第5.4节中描述)
  • 由此产生的模型具有丰富的能力。它们可以用至少八种语言回答问题、编写高质量代码、解决复杂推理问题,并且开箱即用地或以零样本方式使用工具
  • 论文还进行了实验,通过组合方法为 Llama 3 添加图像、视频和语音能力,论文研究的方法包括图28所示的三个附加阶段:
    • 多模态编码器预训练 :论文分别训练图像和语音编码器
      • 论文在大量图像-文本对上训练图像编码器,这教会模型视觉内容与该内容的自然语言描述之间的关系
      • 论文的语音编码器使用自监督方法进行训练,该方法掩盖语音输入的部分内容,并试图通过离散 token 表示重建被掩盖的部分
      • 结果,模型学习了语音信号的结构
      • 图像编码器的详细信息见第7节,语音编码器的详细信息见第8节
    • 视觉适配器训练 :论文训练一个适配器,将预训练的图像编码器集成到预训练的语言模型中
      • 该适配器由一系列交叉注意力层组成,将图像编码器的表示输入到语言模型中
      • 适配器在文本-图像对上进行训练,这使图像表示与语言表示保持一致
      • 在适配器训练期间,论文还更新图像编码器的参数,但有意不更新语言模型的参数
      • 论文还在图像适配器之上的配对视频-文本数据上训练视频适配器,这使模型能够跨帧聚合信息。详情见第7节
    • 语音适配器训练 :最后,论文通过适配器将语音编码器集成到模型中,该适配器将语音编码转换为可以直接输入到微调语言模型的 token 表示
      • 在监督微调阶段,适配器和编码器的参数联合更新,以实现高质量的语音理解
      • 在语音适配器训练期间,论文不改变语言模型
      • 论文还集成了文本到语音系统。详情见第8节
  • 论文的多模态实验产生的模型可以识别图像和视频的内容,并支持通过语音界面进行交互。这些模型仍在开发中,尚未准备好发布

Pre-training

  • 语言模型预训练包括:
    • (1) 大规模训练语料库的精心挑选(Curation)和过滤;
    • (2) 模型架构的开发以及确定模型规模的相应 Scaling Laws ;
    • (3) 大规模高效预训练技术的开发;
    • (4) 预训练方案的制定
  • 下面分别介绍这些组成部分

Pre-Training Data

  • 论文从包含截至 2023年 底知识的各种数据源中创建语言模型预训练数据集
  • 论文对每个数据源应用多种去重方法和数据清理机制,以获得高质量的 token。论文移除了包含大量个人可识别信息(personally identifiable information,PII)的领域和已知包含成人内容的领域
Web Data Curation
  • 论文利用的大部分数据来自网络,下面描述论文的清理过程
  • PII和安全过滤(PII and safety filtering) :除其他缓解措施外,论文实施了过滤器,旨在从可能包含不安全内容或大量 PII 的网站、根据 Meta 各种安全标准被列为有害的领域,以及已知包含成人内容的领域中移除数据
  • 文本提取和清理(Text extraction and cleaning) :论文处理非截断网页的原始 HTML 内容,以提取高质量的多样化文本
    • 为此,论文构建了一个自定义解析器,提取 HTML 内容并优化样板移除的精度和内容召回率
    • 论文通过人类评估来评估解析器的质量,将其与优化类文章内容的流行第三方 HTML 解析器进行比较,发现它表现更优
    • 论文仔细处理包含数学和代码内容的 HTML 页面,以保留这些内容的结构
    • 论文保留图像的 alt 属性文本,因为数学内容通常以预渲染图像的形式呈现,而数学内容也在 alt 属性中提供
    • 论文通过实验评估不同的清理配置
    • 论文发现,与纯文本相比,markdown 对主要在网络数据上训练的模型的性能有害,因此论文移除了所有 markdown Token
  • 去重(De-duplication) :论文在URL、文档和行级别应用多轮去重:
    • URL级别去重(URL-level de-duplication) :论文在整个数据集上进行 URL 级别去重
      • 对于每个 URL 对应的页面,论文保留最新版本
    • 文档级别去重(Document-level de-duplication) :论文在整个数据集上进行全局 MinHash(1997) 去重,以移除近重复文档
    • 行级别去重(Line-level de-duplication) :论文执行类似于 ccNet(2019) 的激进行级别去重
      • 在每 30M 文档的桶中,论文移除出现超过 6次 的行
      • 尽管论文的手动定性分析表明,行级别去重不仅移除了各种网站的剩余样板(如导航菜单、Cookie 警告),还移除了频繁的高质量文本 ,但论文的实证评估显示性能有显著提升
  • 启发式过滤(Heuristic filtering) :论文开发了启发式方法来移除额外的低质量文档、离群值和重复过多的文档。一些启发式方法的例子包括:
    • 论文使用重复 n-gram 覆盖率比率(2021)来移除由重复内容(如日志或错误消息)组成的行
      • 这些行可能非常长且唯一,因此无法通过行去重过滤
    • 论文使用“脏词(dirty word)”计数(2020)来过滤未被域名 blockList 覆盖的成人网站
    • 论文使用 token 分布的 Kullback-Leibler 散度来过滤与训练语料库分布相比包含过多离群 token 的文档
  • 基于模型的质量过滤(Model-based quality filtering) :论文还尝试应用各种基于模型的质量分类器来子选择高质量 token,这些包括:
    • 使用快速分类器(fast classifiers,如fasttext(2017)),其训练用于识别给定文本是否会被维基百科引用(2023a)
    • 更计算密集的基于 Roberta 的分类器(2019a),其在 Llama 2 预测上训练
      • 为了训练基于 Llama 2 的质量分类器,论文创建了一个清理后的网页文档训练集,描述质量要求,并指示 Llama 2 的聊天模型确定文档是否满足这些要求
      • 为了效率,论文使用 DistilRoberta(2019) 为每个文档生成质量分数
    • 论文通过实验评估各种质量过滤配置的效果
  • 代码和推理数据(Code and reasoning data) :与 DeepSeek-AI 等(2024)类似,论文构建了特定领域的 Pipeline 来提取与代码和数学相关的网页
    • 具体而言,代码和推理分类器都是在 Llama 2 标注(annotation)的网络数据上训练的 DistilRoberta 模型
    • 与上述通用质量分类器不同,论文进行提示微调,以针对包含数学推导、STEM 领域推理以及与自然语言交织的代码的网页
    • 由于代码和数学的 token 分布与自然语言的 token 分布有很大不同,这些 Pipeline 实现了特定领域的 HTML 提取、定制的文本特征和过滤启发式方法
  • 多语言数据(Multilingual data) :与上述英语处理 Pipeline 类似,论文实施过滤器以移除可能包含 PII 或不安全内容的网站数据。论文的多语言文本处理 Pipeline 有几个独特功能:
    • 论文使用基于 fasttext 的语言识别模型将文档分类为176种语言
    • 论文在每种语言的数据内进行文档级别和行级别去重
    • 论文应用特定语言的启发式方法和基于模型的过滤器来移除低质量文档
  • 此外,论文使用基于多语言 Llama 2 的分类器对多语言文档进行质量排名,以确保优先考虑高质量内容
  • 论文通过实验确定预训练中使用的多语言 token 数量,平衡模型在英语和多语言基准上的性能
Determining the Data Mix
  • 为了获得高质量的语言模型,仔细确定预训练数据混合中不同数据源的比例至关重要
  • 论文确定此数据混合的主要工具是知识分类和 Scaling Laws 实验
  • 知识分类 :论文开发了一个分类器来对网络数据中包含的信息类型进行分类,以更有效地确定数据混合
    • 论文使用此分类器对网络上过度表示的数据类别(如艺术和娱乐)进行下采样
  • 数据混合的 Scaling Laws :为了确定最佳数据混合,论文进行 Scaling Laws 实验
    • 其中论文在数据混合上训练几个小模型,并使用该模型预测大型模型在该组合上的性能(见3.2.1节)
    • 论文对不同的数据混合多次重复此过程,以选择新的数据混合候选
    • 随后,论文在该候选数据混合上训练更大的模型,并在几个关键基准上评估该模型的性能
  • 数据混合总结(Data mix summary) :论文最终的数据混合包含约 50% 的通用知识 token、25% 的数学和推理 token、17% 的代码 token 和 8% 的多语言token
    • 理解:多语言仅 8%?那中文一定比较一般
Annealing Data
  • 根据经验,论文发现对少量高质量代码和数学数据进行退火(见3.4.3节)可以提升预训练模型在关键基准上的性能
  • 与 Li等(2024b)类似,论文使用数据混合进行退火,该组合对选定领域的高质量数据进行上采样
    • 论文的退火数据中不包含常用基准的任何训练集 ,这使论文能够评估 Llama 3 的真实少样本学习能力和域外泛化能力
      • 理解:很专业,不包括基准测试数据集,保证评估公平性,防止刷榜
  • 遵循 OpenAI(2023a),论文评估了在 GSM8k(2021) 和 MATH(2021b) 训练集上进行退火的效果
    • 论文发现,退火使预训练的 Llama 3 8B 模型在 GSM8k 和 MATH 验证集上的性能分别提升了 24.0% 和 6.4%
    • 但对 405B 模型的提升可以忽略不计,这表明论文的旗舰模型具有强大的上下文学习和推理能力 ,不需要特定的域内训练样本即可获得强大性能
  • 使用退火评估数据质量(Using annealing to assess data quality) :与 Blakeney等(2024)类似,论文发现退火使我们能够判断小型特定领域数据集的价值
    • 论文通过对 50% 训练的 Llama 3 8B 模型的学习率在 40B token 上线性退火至 0 来衡量此类数据集的价值
    • 在这些实验中,论文为新数据集分配 30% 的权重,剩余 70% 权重分配给默认数据混合
      • 问题:这里说的权重是什么?是梯度权重吗?
    • 使用退火评估新数据源比为每个小型数据集执行 Scaling Laws 实验更高效

Model Architecture

  • Llama 3 使用标准的 Dense Transformer 架构(2017)
    • 在模型架构方面,它与 Llama 和 Llama 2(2023a,b) 没有显著差异;
    • 论文的性能提升主要由数据质量和多样性的改进以及训练规模的增加所驱动
  • 与 Llama 2 相比,论文做了一些小的修改:
    • 论文使用分组查询注意力(grouped query attention,GQA;(2023))
      • 带有 8 个键值头,以提高推理速度并减少解码期间键值缓存的大小
    • 论文使用注意力掩码,防止同一序列中不同文档之间的自注意力
      • 论文发现此更改在标准预训练期间影响有限 ,但在对非常长的序列进行持续预训练时很重要
    • 论文使用包含 128K token 的词汇表
      • 论文的 token 词汇表将 tiktoken3 tokenizer 的 100K token 与额外的 28K token 结合,以更好地支持非英语语言
      • 与 Llama 2 tokenizer 相比,论文的新 tokenizer 将英语数据样本的压缩率从每个 token 3.17 字符提高到 3.94 字符
        • 这使模型能够在相同的训练计算量下“读取”更多文本
      • 论文还发现,从选定的非英语语言中添加 28K token 可以提高压缩率和下游性能,且对英语 tokenization 没有影响
    • 论文将 RoPE 基础频率超参数增加到 500,000
      • 这使论文能够更好地支持更长的上下文;
      • Xiong等(2023)表明该值对长达 32768 的上下文长度有效
  • Llama 3 405B 使用具有 126层、16384 的 token 表示维度和 128 个注意力头的架构;详情见表3
  • 根据论文数据上的 Scaling Laws ,对于论文的 \(3.8×10^{25}\) FLOPs 训练预算,这导致模型大小接近计算最优
Scaling Laws
  • 在给定论文的预训练计算预算的情况下,论文开发 Scaling Laws (2022; 2020)来确定旗舰模型的最佳大小
  • 除了确定最佳模型大小外,一个主要挑战是预测旗舰模型在下游基准任务上的性能,这是由于几个问题:
    • (1) 现有 Scaling Laws 通常仅预测 next token 预测损失 ,而不是特定基准性能
    • (2) Scaling Laws 可能有噪声且不可靠 ,因为它们是基于使用小计算预算进行的预训练运行开发的(2022b)
  • 为了应对这些挑战,论文实施了两阶段方法来开发准确预测下游基准性能的 Scaling Laws :
    • 1)论文首先在计算最优模型在下游任务上的负对数似然与训练 FLOPs 之间建立相关性
    • 2)接下来,论文利用 Scaling Laws 模型和使用更高计算 FLOPs 训练的旧模型 ,将下游任务的负对数似然与任务准确性相关联
      • 在这一步中,论文特别利用了 Llama 2 系列模型
    • 这种方法使论文能够预测给定计算最优模型的特定训练 FLOPs 下的下游任务性能
      • 论文使用类似的方法选择论文的预训练数据混合(见3.4节)
  • Scaling Laws 实验(Scaling law experiments) :具体而言,论文通过使用 \(6×10^{18}\) FLOPs 到 \(10^{22}\) FLOPs 的计算预算预训练模型来构建论文的 Scaling Laws
    • 在每个计算预算下,论文训练参数在 40M 到 16B 之间的模型,在每个计算预算下使用模型大小的子集
      • 理解:使用不同的计算预算和不同的模型大小做交叉训练,试图找到模型大小和计算预算的最优的配置点
      • 补充:FLOPs 是浮点运算次数,是模型复杂度的评估指标,用于评估一个模型的复杂度
    • 以上训练中,超参数配置如下:
      • 使用带有 2000个 训练步骤线性预热的余弦学习率调度
      • 峰值学习率根据模型大小设置在 \(2×10^{-4}\) 到 \(4×10^{-4}\) 之间
      • 余弦衰减设置为峰值的 0.1(理解:这里指最终衰减后的学习率是峰值的 10%)
      • 每个步骤的权重衰减(Weight Decay)设置为该步骤学习率的 0.1 倍
        • 理解:权重衰减是正则化技术,用于抑制模型过拟合,本质上是在损失函数中添加参数的 L2 范数惩罚项,这种跟着学习率自适应变化的设置使权重衰减随学习率变化而自适应调整,增强了正则化的灵活性
        • 问题:这种方法常用吗?
      • 论文为每个计算规模使用固定的 Batch Size,范围在 250K 到 4M 之间
        • 问题:这里的「250K 到 4M」是指每个 Batch 的 token 数还是 Sequence 数?
          • 回答:应该是 token 数,详情见后文的描述
          • 但无论如何,Llama 3 训练使用的 Batch Size 非常大
    • 这些实验产生了图2中的 IsoFLOPs 曲线
      • 这些曲线中的损失是在单独的验证集上测量的
      • 论文使用二次多项式拟合测量的损失值,并确定每个抛物线的最小值
      • 论文将抛物线的最小值称为相应预训练计算预算下的计算最优模型
      • 补充:对图2 的理解 :
        • 每条线表示固定计算预算下不同 数据量(tokens)对应的效果
        • 注意:由于总的计算预算是固定的 ,显然 tokens 确定时,数据量也会自动确定 ,此时对应的模型 Size 也确定了(因为要保持计算预算固定)
        • 实际上,表2 画出的图中,每个曲线的每个点都代表一个模型 Size ,模型 Size 确定以后,固定 计算预算 下的 tokens 自然就出来了(横轴也就确定了)
    • 论文使用以这种方式确定的计算最优模型来预测特定计算预算下的最佳训练 token 数量
      • 论文假设计算预算 \(C\) 与最佳训练 token 数量 \(N^*(C)\) 之间存在幂律关系:
        $$N^*(C) = A C^\alpha$$
    • 论文使用图2 中的数据拟合 \(A\) 和 \(\alpha\)
      • 论文发现 \((\alpha, A) = (0.53, 0.29)\) ;
      • 理解:这是用最优的点(对应给定计算预算下,最优 tokens ,最优模型 Size)来拟合的
    • 相应的拟合如图3 所示
      • 将得到的 Scaling Laws 外推到 \(3.8×10^{25}\) FLOPs (这个是 Meta AI 的总算力,也就是总训练预算)表明,在 16.55T token 上训练一个 402B 参数的模型是最优的
    • 一个重要的观察是,随着计算预算的增加,IsoFLOPs 曲线在最小值附近变得更平坦
      • 这意味着旗舰模型的性能对模型大小和训练 token 之间权衡的小变化相对稳健
      • 基于这一观察,论文最终决定训练一个具有 405B 参数的旗舰模型
  • 预测下游任务性能(Predicting performance on downstream tasks) :论文使用得到的计算最优模型来预测旗舰 Llama 3 模型在基准数据集上的性能
    • 首先,论文将基准中正确答案的(归一化)负对数似然与训练 FLOPs 线性相关
    • 在该分析中,论文仅使用在上述数据混合上训练到 \(10^{22}\) FLOPs 的 Scaling Laws 模型
    • 接下来,论文使用 Scaling Laws 模型和 Llama 2 模型(使用 Llama 2 数据混合和 tokenizer 训练)在对数似然和准确性之间建立 sigmoidal 关系
    • 论文在 ARC Challenge 基准上展示了该实验的结果(图4)
    • 论文发现这种两步 Scaling Laws 预测(外推超过四个数量级)相当准确:它仅略微低估了旗舰 Llama 3 模型的最终性能

Infrastructure, Scaling, and Efficiency

  • 论文描述了支持 Llama 3 405B 大规模预训练的硬件和基础设施,并讨论了导致训练效率提升的几项优化
Training Infrastructure
  • Llama 1 和 Llama 2 模型在 Meta 的 AI 研究超级集群(2022)上训练
  • 随着论文进一步扩展, Llama 3 的训练迁移到了 Meta 的生产集群(2024)
  • 这种设置针对生产级可靠性进行了优化,这在论文扩展训练时至关重要
  • 计算(Compute) :
    • Llama 3 405B 在多达 16000 个 H100 GPU 上训练,每个 GPU 以 700W TDP 运行,配备80GB HBM3,使用 Meta 的 Grand Teton AI 服务器平台(2022)
    • 每个服务器配备 8 个 GPU 和 2 个 CPU
    • 在服务器内,8 个 GPU 通过 NVLink 连接
    • 训练作业使用 MAST(2024)调度,这是 Meta 的全球规模训练调度器
  • 存储(Storage) :
    • 使用 Tectonic(2021)(Meta 的通用分布式文件系统)为 Llama 3 预训练构建存储架构(2024)
    • 它提供 7500台 配备 SSD 的服务器中的 240PB 存储,支持 2TB/s 的可持续吞吐量和 7TB/s 的峰值吞吐量
    • 一个主要挑战是支持高度突发的 checkpoint 写入,这会在短时间内使存储架构饱和
    • checkpoint 保存每个 GPU 的模型状态,每个 GPU 从 1MB 到 4GB 不等,用于恢复和调试
    • 论文旨在最小化 checkpoint 期间的 GPU 暂停时间,并增加 checkpoint 频率,以减少恢复后丢失的工作量
  • 网络(Network)
    • Llama 3 405B 使用基于 Arista 7800 和 Minipack2 开放计算项目 OCP 机架交换机的RoCE(融合以太网远程直接内存访问)架构
      • Llama 3 系列中的较小模型使用 Nvidia Quantum2 InfiniBand 架构训练。RoCE 和 InfiniBand 集群都利用 GPU 之间的 400 Gbps 互连。尽管这些集群的基础网络技术不同,但论文对它们进行调优,以为这些大型训练工作负载提供等效性能
      • 论文进一步详细阐述论文的 RoCE 网络,因为论文完全拥有其设计
    • 网络拓扑(Network topology) :
      • 论文的基于 RoCE 的 AI 集群由 24000 个 GPU5 组成,通过三层 Clos 网络(2024)连接
      • 在底层,每个机架托管 16 个 GPU,分为两台服务器,并通过单个 Minipack2 架顶式(ToR)交换机连接
      • 在中间层,192 个这样的机架通过集群交换机连接,形成一个具有完整二分带宽的 3072 个 GPU 的 pod,确保无超额订阅
      • 在顶层,同一数据中心大楼内的八个这样的 pod 通过聚合交换机连接,形成一个 24000 个 GPU 的集群
      • 但聚合层的网络连接不保持完整的二分带宽,而是具有1:7的超额订阅比率
      • 论文的模型并行方法(见3.3.2节)和训练作业调度器(2024)都经过优化,以了解网络拓扑,旨在最小化跨 pod 的网络通信
    • 负载平衡(Load balancing) :
      • LLM训练产生难以使用传统方法,如等价多路径(Equal-Cost Multi-Path,ECMP)路由,在所有可用网络路径上平衡负载的 fat network flows
      • 为了应对这一挑战,论文采用了两种技术
        • 首先,论文的集体库在两个 GPU 之间创建16个网络流,而不仅仅是一个,从而减少每个流的流量并提供更多流用于负载平衡
        • 其次,论文的增强型ECMP(E-ECMP)协议通过对数据包的RoCE报头中的附加字段进行哈希处理,有效地在不同网络路径上平衡这16个流
    • 拥塞控制(Congestion control)
      • 论文在骨干网中使用深缓冲区交换机(2024)来适应由集体通信模式引起的瞬态拥塞和缓冲。这种设置有助于限制由集体通信模式和慢速服务器导致的持续拥塞及网络背压的影响,这些在训练中很常见
      • 最后,通过 E-ECMP 实现的更好负载平衡显著降低了拥塞的可能性
      • 通过这些优化,论文成功运行了 24000 个 GPU 的集群,而无需使用传统的拥塞控制方法,如数据中心量化拥塞通知(DCQCN)
        • 补充:24000 个 GPU,666!
Parallelism for Model Scaling
  • 为了对最大的模型进行训练缩放,论文使用 4D 并行(一种结合了四种不同并行方法的技术)来对模型进行分片(shard)
  • 这种方法有效地将计算分布在许多 GPU 上,并确保每个 GPU 的模型参数、优化器状态、梯度和激活适合其 HBM
  • 论文的 4D 并行性实现如图5 所示,它结合了:
    • 张量并行(tensor parallelism,TP;2012;2019;2023)
      • 张量并行性将单个权重张量分割成不同设备上的多个块
    • 流水线并行(pipeline parallelism,PP;2019;2021;2023)
      • 流水线并行性按层将模型垂直划分为阶段,使不同设备可以并行处理完整模型流水线的不同阶段
    • 上下文并行(context parallelism,CP;2023a)
      • 上下文并行性将输入上下文划分为段,减少超长序列长度输入的内存瓶颈
    • 数据并行(data parallelism,DP;2020;2021;2023b)
      • 论文使用全分片数据并行性(FSDP;2020;2021;2023b),它在实现数据并行性的同时对模型、优化器和梯度进行分片,该并行性在多个 GPU 上并行处理数据,并在每个训练步骤后进行同步
  • 论文对 Llama 3 使用 FSDP 来分片优化器状态和梯度,但对于模型分片,论文在前向计算后不进行重新分片,以避免反向传播期间额外的 All-Gather 通信
  • GPU 利用率(GPU utilization) :
    • 通过仔细调整并行性配置、硬件和软件,论文为表4 中所示的配置实现了 38%-43% 的总体 BF16 模型浮点运算利用率(Model FLOPs Utilization,MFU;2023)
    • 与使用 DP=64 的 8000个 GPU 上 43% 的 MFU 相比,在使用 DP=128 的 16000个 GPU 上,MFU 略降至41%,这是由于在训练期间为保持全局每批 token 数恒定 ,每个 DP 组需要更小的 Batch Size
      • 理解:Batch Size 越小,MFU 会越低?
  • 流水线并行性改进(Pipeline parallelism improvements) ,论文在现有实现中遇到了几个挑战:
    • Batch Size 限制(Batch size constraint) :当前实现对每个 GPU 支持的 Batch Size 有限制,要求其可被流水线阶段数整除
      • 对于图6中的示例,流水线并行性的深度优先调度(DFS;2021)要求 \(N = PP = 4\),而广度优先调度(BFS;2023)要求 \(N = M\),其中 \(M\) 是 Micro-batches 的总数,\(N\) 是同一阶段前向或后向的连续 Micro-batches 数
      • 但预训练通常需要灵活调整 Batch Size
    • 内存不平衡(Memory imbalance) :现有流水线并行性实现导致资源消耗不平衡
      • 由于 Embedding 和预热 Micro-batches,第一阶段消耗更多内存
    • 计算不平衡(Computation imbalance) :在模型的最后一层之后,论文需要计算输出和损失,使该阶段成为执行延迟瓶颈
  • 为了解决这些问题,论文修改了如图6 所示的流水线调度
    • 允许灵活设置 \(N\) (在这种情况下 \(N=5\))
    • 可以在每批中运行任意数量的 Micro-batches,这使论文能够:
      • (1) 在大规模 Batch Size 受限时,运行比阶段数更少的 Micro-batches ;
      • (2) 运行更多 Micro-batches 以隐藏 point-to-point 通信,在 DFS 和 BFS 之间找到最佳点,以实现最佳通信和内存效率
    • 为了平衡流水线,论文分别从第一阶段和最后阶段各减少一个 Transformer 层
      • 这意味着第一阶段的第一个模型块仅包含 Embedding,最后阶段的最后一个模型块仅包含输出投影和损失计算
      • 为了减少流水线气泡(bubbles),论文在一个流水线 Rank 上使用具有 \(V\) 个流水线阶段的交错调度(2021)
        • 总体流水线气泡比率为 \(\frac{PP-1}{V*M}\)
      • 论文在 PP 中采用异步 point-to-point 通信,这大大加快了训练速度,尤其是在文档掩码引入额外计算不平衡的情况下
      • 论文启用 TORCH_NCCL_AVOID_RECORD_STREAMS 以减少异步 point-to-point 通信的内存使用
      • 为了降低内存成本,基于详细的内存分配分析,论文主动释放未来计算不会使用的张量,包括每个流水线阶段的输入和输出张量
      • 通过这些优化,论文可以在不进行激活 checkpoint 的情况下 ,对 8K token 的序列进行 Llama 3 的预训练
  • 长序列的上下文并行性(Context parallelism for long sequences)
    • 论文利用上下文并行性(CP)来提高 Llama 3 上下文长度缩放时的内存效率,并支持长达 128K 长度的极长序列训练
    • 在 CP 中,论文跨序列维度进行分区,具体来说,论文将输入序列划分为 2个 CP 块,因此每个 CP Rank 接收两个块以实现更好的负载平衡
    • 第 \(i\) 个 CP Rank 接收第 \(i\) 个和 \((2×CP-1-i)\) 个块
    • 与现有 CP 实现(在环形结构中重叠通信和计算;2023a)不同,论文的 CP 实现采用基于 All-Gather 的方法,其中论文首先 All-Gather 键(K)和值(V)张量,然后计算本地查询(Q)张量块的注意力输出
    • 尽管 All-Gather 通信延迟暴露在关键路径上,但论文仍然采用这种方法,主要有两个原因:
      • (1) 基于 All-Gather 的CP注意力更容易且更灵活地支持不同类型的注意力掩码,如文档掩码
      • (2) 由于使用 GQA(2023),通信的 K 和 V 张量比 Q 张量小得多,因此暴露的 All-Gather 延迟很小
        • 因此,注意力计算的时间复杂度( \(O(S^2)\) ,其中 \(S\) 表示完整因果掩码中的序列长度)比 All-Gather ( \(O(S)\) )大一个数量级,使得 All-Gather 开销可以忽略不计
  • 网络感知并行性配置(Network-aware parallelism configuration)
    • 并行性维度的顺序[TP, CP, PP, DP]针对网络通信进行了优化
    • 最内层并行性需要最高的网络带宽和最低的延迟,因此通常限制在同一服务器内
    • 最外层并行性可能跨多跳网络分布,应容忍更高的网络延迟
    • 因此,根据网络带宽和延迟的要求,论文按[TP, CP, PP, DP]的顺序放置并行性维度
    • DP(即FSDP)是最外层并行性,因为它可以通过异步预取分片模型权重和减少梯度来容忍更长的网络延迟
    • 在避免 GPU 内存溢出的同时,确定具有最小通信开销的最佳并行性配置具有挑战性
    • 论文开发了内存消耗估计器和性能预测工具,帮助论文探索各种并行性配置,并有效预测整体训练性能和识别内存差距
  • 数值稳定性(Numerical stability) :通过比较不同并行性设置下的训练损失,论文修复了几个影响训练稳定性的数值问题
    • 为了确保训练收敛,论文在多个 Micro-batches 的反向计算期间使用 FP32 梯度累积,并在 FSDP 中跨数据并行工作者以 FP32 Reduce-Scatter 梯度
    • 对于在正向计算中多次使用的中间张量(如视觉编码器输出),反向梯度也以 FP32 累积
Collective Communication
  • 论文用于 Llama 3 的集体通信库基于 Nvidia 的 NCCL 库的分支,称为 NCCLX
  • NCCLX 显著提高了 NCCL 的性能,尤其是在更高延迟的网络中
  • 回想一下,并行性维度的顺序是[TP, CP, PP, DP],其中 DP 对应于 FSDP
  • 最外层并行性维度 PP 和 DP 可能通过多跳网络通信,延迟高达数十微秒
  • 原始的 NCCL 集体操作(FSDP 中的 All-Gather 和 Reduce-Scatter ,以及 PP 中的 point-to-point)需要数据分块和分段数据复制,这种方法导致几个效率低下的问题,包括:
    • (1) 需要在网络上交换大量小控制消息以促进数据传输;
    • (2) 额外的内存复制操作;
    • (3) 使用额外的 GPU 周期进行通信
  • 对于 Llama 3 训练,论文通过调整分块和数据传输以适应论文的网络延迟(对于大型集群,延迟可能高达数十微秒)来解决这些效率低下问题的一部分
  • 论文还允许小控制消息以更高优先级穿越论文的网络,特别是避免在深缓冲区核心交换机中被队首阻塞。论文为未来 Llama 版本正在进行的工作涉及对 NCCLX 进行更深入的更改,以全面解决所有上述问题
Reliability and Operational Challenges
  • 16000个 GPU 训练的复杂性和潜在故障场景超过了作者运行过的更大 CPU 集群
  • 此外,训练的同步特性使其容错性较低(单个GPU故障可能需要整个作业重启)
  • 尽管存在这些挑战,对于 Llama 3 ,论文实现了超过 90% 的有效训练时间 ,同时支持自动集群维护 ,如固件和 Linux 内核升级(2024),这导致每天至少一次训练中断
  • 有效训练时间衡量的是在经过时间中用于有用训练的时间比例
  • 在预训练的 54天 快照期间,论文总共经历了 466 次作业中断
    • 其中,47次 是由于自动维护操作(如固件升级)或操作员发起的操作(如配置或数据集更新)导致的计划中断
    • 其余 419次 是意外中断,分类如表5 所示
      • 约78%的意外中断归因于已确认的硬件问题(如 GPU 或主机组件故障)或疑似硬件相关问题(如静默数据损坏和计划外的单个主机维护事件)
      • GPU 问题是最大的类别,占所有意外问题的 58.7%
      • 尽管故障数量众多,但在此期间仅需要三次重大人工干预,其余问题由自动化处理
  • 为了增加有效训练时间,论文减少了作业启动和 checkpoint 时间,并开发了快速诊断和问题解决工具
  • 论文广泛使用 PyTorch 的内置 NCCL flight recorder (2024)
    • 该功能将集体元数据和堆栈跟踪捕获到环形缓冲区中,从而允许论文在大规模下快速诊断挂起和性能问题,尤其是关于NCCLX的问题
    • 使用此功能,论文有效地记录每个通信事件和每个集体操作的持续时间,并在 NCCLX watchdog 或 heartbeat 超时情况下自动转储跟踪数据
  • 通过在线配置更改(2015),我们可以根据需要有选择地启用更多计算密集型跟踪操作和元数据收集,而无需代码发布或作业重启
  • 在大规模训练中调试问题因论文网络中 NVLink 和 RoCE 的混合使用而变得复杂
    • 通过 NVLink 的数据传输通常通过 CUDA 内核发出的加载/存储操作进行,远程 GPU 或 NVLink 连接的故障通常表现为 CUDA 内核内停滞的加载/存储操作,而不会返回明确的错误代码
    • NCCLX 通过与 PyTorch 的紧密协同设计提高了故障检测和定位的速度和准确性,允许 PyTorch 访问 NCCLX 的内部状态并跟踪相关信息
    • 尽管无法完全防止 NVLink 故障导致的停滞,但论文的系统监控通信库的状态,并在检测到此类停顿时自动超时
    • 此外,NCCLX 跟踪每个 NCCLX 通信的内核和网络活动,并提供失败 NCCLX 集体的内部状态快照,包括所有 Rank 之间已完成和待处理的数据传输
    • 论文分析此数据以调试 NCCLX 缩放问题
  • 有时,硬件问题可能导致仍在运行但速度缓慢的掉队者,这些掉队者难以检测
    • 即使单个掉队者也会减慢数千个其他 GPU 的速度,通常表现为正常运行但缓慢的通信
    • 论文开发了工具来优先处理来自选定进程组的潜在问题通信
    • 通过调查仅几个主要可疑对象,论文通常能够有效识别掉队者
  • 一个有趣的观察是环境因素对大规模训练性能的影响
    • 对于 Llama 3 405B,论文注意到基于时间的昼夜 1%-2% 的吞吐量变化
    • 这种波动是由于中午较高的温度影响 GPU 动态电压和频率缩放造成的
  • 在训练期间,数万个 GPU 可能同时增加或减少功耗,例如,由于所有 GPU 等待 checkpoint 或集体通信完成,或整个训练作业的启动或关闭
  • 当这种情况发生时,可能导致数据中心的功耗瞬间波动数十兆瓦 ,达到电网的极限
  • 随着论文为未来更大的 Llama 模型扩展训练 ,这是作者面临的持续挑战

Training Recipe

  • 用于预训练 Llama 3 405B 的方案包括三个主要阶段:
    • (1) 初始预训练(Initial Pre-Training);
    • (2) 长上下文预训练(Long Context Pre-Training);
    • (3) 退火(Annealing)
  • 下面分别描述这三个阶段(论文使用类似的方案预训练 8B 和 70B 模型)
Initial Pre-Training
  • 论文使用 AdamW 预训练 Llama 3 405B
    • 峰值学习率为 \(8×10^{-5}\)
    • 8000步 线性预热
    • 余弦学习率调度在 1200000步 内衰减至 \(8×10^{-7}\)
  • 论文在训练早期使用较小的 Batch Size 以提高训练稳定性,随后增加 Batch Size 以提高效率
    • 使用 4M token 的初始 Batch Size 和 4096 的序列长度
      • 问题:论文中给的 Batch Size 都是 token 为单位的吗?
      • 回答:是的,在 NLP 中,以 token 为单位计量,能更精确地控制模型训练时处理的数据量
    • 在预训练 252M token 后,将 Batch Size 翻倍至 8M token,序列长度提升至 8192
    • 在预训练 2.87T token 后,论文再次将 Batch Size 翻倍至 16M
  • 论文发现此训练方案非常稳定:论文观察到很少的损失尖峰(loss spikes) ,并且不需要干预来纠正模型训练发散
  • 调整数据混合(Adjusting the data mix) :在训练期间,论文对预训练数据混合进行了几次调整,以提高模型在特定下游任务上的性能
    • 在预训练期间增加了非英语数据的百分比,以提高 Llama 3 的多语言性能
    • 对数学数据进行上采样 ,以提高模型的数学推理性能
    • 在预训练的后期阶段添加了更多近期网络数据 ,以推进模型的知识截止日期
    • 对后来被确定为质量较低的预训练数据子集进行下采样
Long Context Pre-Training
  • 在预训练的最后阶段,论文在长序列上训练以支持高达 128K token 的上下文窗口
  • 不早期在长序列上训练,因为自注意力层中的计算随序列长度的平方增长
  • 以增量方式增加支持的上下文长度,预训练直到模型成功适应增加的上下文长度
  • 通过测量以下两点来评估成功适应:
    • (1) 模型在短上下文评估上的性能已完全恢复;
    • (2) 模型完美解决该长度的“大海捞针(needle in a haystack)”任务
  • 在 Llama 3 405B 预训练中,论文分六个阶段逐渐增加上下文长度,从原始的 8K 上下文窗口开始,最终达到 128K 上下文窗口
    • 此长上下文预训练阶段使用约 800B 训练 token 进行
Annealing(退火)
  • 在最后 40M token 的预训练期间,论文将学习率线性退火至 0,保持 128K 的上下文长度
  • 退火阶段,论文还调整数据混合以对高质量数据源进行上采样 ,见原文 3.1.3 节(Annealing Data)
  • 论文在退火期间计算模型 checkpoint 的平均值(Polyak(1991) averaging),以生成最终的预训练模型
    • 理解:最终的预训练模型的参数不是某个 Checkpoint 的结果,而是退火阶段的平均值

Post-training

  • 论文通过在预训练 checkpoint 的基础上应用多轮后训练(即让模型与人类反馈对齐)来生成经过对齐的 Llama 3 模型
  • 每轮后训练都包括:
    • SFT
    • 偏好优化(DPO):在通过人工标注或合成生成收集的示例上进行直接 DPO
  • 论文的后训练建模和数据方法分别在 4.1节 和 4.2节 中描述
  • 论文在 4.3节 中进一步详细介绍了自定义数据精心挑选策略,以提高推理、编码、事实性、多语言能力、工具使用、长上下文和精确指令遵循等方面的性能

Modeling

  • 论文后训练策略的核心是奖励模型和语言模型
    • 首先,使用人工标注的偏好数据在预训练 checkpoint 的基础上训练奖励模型(见4.1.2节)
    • 然后,使用监督微调(SFT;2022)对预训练 checkpoint 进行微调,并通过直接偏好优化(DPO;2024)进一步对齐 checkpoint
  • 此过程如图7 所示
    • 除非另有说明,论文的建模过程适用于 Llama 3 405B,为简单起见,论文将 Llama 3 405B 称为 Llama 3
Chat Dialog Format
  • 为了将 LLM 调整为适合人机交互的模式,论文需要定义一种聊天对话协议,使模型能够理解人类指令并执行对话任务
  • 与前身相比,Llama 3 具有新的功能,如工具使用(原文 4.3.5节),这可能需要在单个对话轮次中生成多条消息并发送到不同位置(例如用户、ipython)
    • 为了支持这一点,论文设计了一种新的多消息聊天协议,该协议使用各种特殊头部和终止 Token
    • 头部 Token 用于指示对话中每条消息的来源和目的地
    • 同样,终止 Token 指示何时轮到人类和 AI 发言
Reward Modeling
  • 论文在预训练 checkpoint 的基础上训练一个涵盖不同能力的奖励模型(RM)
  • 训练目标与 Llama 2 相同,只是论文删除了损失中的边际项,因为论文观察到在数据缩放后改进逐渐减少
  • 遵循 Llama 2,论文在过滤掉响应相似的样本后,将所有偏好数据用于奖励建模
  • 除了标准的(chosen,rejected)响应偏好对之外,标注还为某些提示创建第三个“编辑响应(edited response)”
    • 该对中的选择响应会被进一步编辑以改进(见4.2.1节)
    • 因此,每个偏好排名样本有两个或三个具有明确排名的响应(edited > chosen > rejected)
    • 在训练期间,论文将提示和多个响应连接成一行,并随机打乱响应顺序
      • 问题:响应之间 token 可见吗?是否最后一个 token 上添加奖励 loss?
    • 这是对标准场景(将响应放在单独行计算分数)的近似,但在论文的消融实验中,这种方法提高了训练效率,且没有准确性损失
Supervised Finetuning
  • 使用奖励模型对论文的人工标注提示进行拒绝采样,具体细节在4.2节中描述
  • 将此拒绝采样数据与其他数据源(包括合成数据)结合,论文使用目标 token 的标准交叉熵损失(同时屏蔽提示 token 的损失)对预训练语言模型进行微调
  • 有关数据混合的更多详细信息,请参见4.2节
  • 论文将此阶段称为监督微调(SFT;2022a)(虽然许多训练目标是模型生成的)
  • 论文最大的模型以 \(10^{-5}\) 的学习率进行微调,持续 8.5K 至 9K 步
    • 问题:SFT 时的样本数和 Batch Size 是多少?
  • 论文发现这些超参数设置在不同轮次和数据混合中都能很好地工作
Direct Preference Optimization
  • 论文使用 DPO 进一步训练论文的 SFT 模型,以实现人类偏好对齐
  • 在训练时,论文主要使用从之前对齐轮次中表现最佳的模型收集的最新批次偏好数据
    • 因此,论文的训练数据更符合每轮中正在优化的策略模型的分布
    • 问题:最佳模型是从多个模型中选出来的吗?是不同 step 的 checkpoint 吗?又如何评估最优模型呢?
  • 论文还探索了策略算法,如 PPO(2017),但发现 DPO 在大规模模型上需要更少的计算,并且表现更好,尤其是在指令遵循基准(如 IFEval(2023))上
  • 对于 Llama 3 ,论文使用 \(10^{-5}\) 的学习率,并将 \(\beta\) 超参数设置为 0.1
  • 此外,论文对 DPO 应用以下算法修改:
    • 在 DPO 损失中屏蔽格式 Token (Masking out formatting tokens in DPO loss) :
      • 论文从损失中的选择和拒绝响应中屏蔽特殊格式 Token ,包括头部和终止 Token (在4.1.1节中描述),以稳定 DPO 训练
      • 论文观察到,让这些 Token 对损失产生影响可能会导致不期望的模型行为,例如尾部重复或突然生成终止 Token
      • 论文假设这是由于 DPO 损失的对比性质,即选择和拒绝响应中常见 Token 的存在会导致冲突的学习目标,因为模型需要同时增加和减少这些 Token 的可能性
    • 使用 NLL 损失进行正则化(Regularization with NLL loss) :
      • 论文在选择序列上添加一个额外的负对数似然(negative log-likelihood,NLL)损失项,缩放系数为 0.2,类似于(2024),它通过维持生成的期望格式并防止选择响应的对数概率降低,帮助进一步稳定 DPO 训练(2024;2024)
Model Averaging
  • 最后,论文对在每个 RM、SFT 或 DPO 阶段使用各种版本的数据或超参数的实验中获得的模型进行平均(2019;2022;2022)
    • 理解:在 Llama 3 的训练过程中,针对每个阶段(RM、SFT、DPO)都进行了多种不同的实验。使用不同版本的数据可以让模型接触到不同分布、不同特点的信息,有助于提高模型的泛化能力和对各种情况的适应性
Iterative Rounds
  • 遵循 Llama 2,论文以上述方法进行六轮
  • 在每个周期中,论文收集新的偏好标注和 SFT 数据,从最新模型中采样合成数据

Post-training Data

  • 后训练数据的组成在语言模型的有用性和行为中起着关键作用
  • 在本节中,论文讨论论文的人工标注程序和偏好数据收集(4.2.1节)、SFT 数据的组成(4.2.2节)以及数据质量控制和清理方法(4.2.3节)
Preference Data
  • 论文的偏好数据标注过程与 Llama 2 类似
    • 每轮后,论文部署多个模型进行标注,并为每个用户提示从两个不同模型中采样两个响应
    • 这些模型可以使用不同的数据混合和对齐方案进行训练,从而具有不同的能力优势(例如代码专业知识),并增加数据多样性
    • 论文要求标注者(annotators)通过将偏好强度分类为四个级别之一来对偏好强度进行评分,这四个级别基于他们对选择响应比拒绝响应的偏好程度:明显更好、更好、稍微更好或大致相同(significantly better, better, slightly better)
  • 我们还在偏好排序后加入了编辑环节,以鼓励标注人员进一步完善被选中的回答
    • 标注人员可直接编辑选中的回答,或通过反馈提示模型改进其自身的回答
    • 因此,我们的部分偏好数据包含三个排序后的回答(edited > chosen > rejected)
  • 在表6中,论文报告了用于 Llama 3 训练的偏好标注统计数据
    • 通用英语涵盖多个子类别,如基于知识的问答或精确指令遵循,这些属于特定能力的范围之外
    • 与 Llama 2 相比,论文观察到提示和响应的平均长度增加,这表明论文在更复杂的任务上训练 Llama 3
    • 论文进行质量分析和人类评估过程,以严格评估收集的数据,使论文能够完善提示并向标注者提供系统的、可操作的反馈
      • 例如,随着 Llama 3 在每轮后改进,论文相应地增加提示的复杂性,以针对模型表现滞后的领域
  • 在每轮后训练中
    • 将当时可用的所有偏好数据用于奖励建模
    • 仅将来自各种能力的最新批次用于 DPO 训练
  • 对于奖励建模和 DPO,论文使用 Token 为选择响应明显优于或优于拒绝响应的样本进行训练,并丢弃响应相似的样本
SFT Data
  • 论文的微调数据主要由以下来源组成:
    • 来自论文人工标注收集的提示,带有拒绝采样的响应
    • 针对特定能力的合成数据(更多详细信息见4.3节)
    • 少量人工精心挑选的数据(更多详细信息见4.3节)
  • 随着后训练轮次的进行,论文开发了更强的 Llama 3 变体,用于收集涵盖广泛复杂能力的更大数据集
  • 在本节中,论文讨论拒绝采样过程的细节和最终 SFT 数据混合的整体组成
  • 拒绝采样(Rejection sampling) :
    • 在拒绝采样(Rejection sampling,RS)期间,对于人工标注期间收集的每个提示(4.2.1节),论文从最新的聊天模型策略采样 K(通常在 10 到 30 之间)个输出 ,并使用论文的奖励模型选择最佳候选 ,这与(2022)一致
      • 注:最新聊天模型通常是前一后训练迭代中表现最佳的 checkpoint,或特定能力中表现最佳的 checkpoint
    • 在后训练的后期轮次中,论文引入系统提示来引导 RS 响应符合所需的语气、风格或格式 ,这可能因能力而异
  • 为了提高拒绝采样的效率,论文采用 PagedAttention(2023)。PagedAttention 通过动态键值缓存分配增强了内存效率
    • 它通过基于当前缓存容量动态调度请求来支持任意输出长度
    • 不幸的是,这存在内存不足时换出的风险
    • 为了消除这种换出开销,论文定义最大输出长度,并仅在有足够内存容纳该长度的输出时才执行请求
    • PagedAttention 还使论文能够在对应于同一提示的所有输出之间共享键值缓存页
    • 总体来说,这使得拒绝采样期间的吞吐量提高了 2 倍以上
  • 整体数据组成(Overall data composition) ,表7 显示了论文“有用性”组合中每个广泛类别的数据统计信息
    • 虽然 SFT 和偏好数据包含重叠的领域,但它们的精心挑选方式不同,从而产生不同的计数统计数据
    • 在4.2.3节中,论文描述了用于对数据样本的主题、复杂性和质量进行分类的技术
    • 在每轮后训练中,论文仔细调整跨这些轴的整体数据混合,以调整跨广泛基准的性能
    • 论文的最终数据混合对一些高质量来源进行多次迭代,并对其他来源进行下采样
Data Processing and Quality Control
  • 由于论文的训练数据大部分是模型生成的,因此需要仔细清理和质量控制
  • 数据清理(Data cleaning) :在早期轮次中,论文在数据中观察到许多不良模式,例如过度使用表情符号或感叹号
    • 因此,论文实施了一系列基于规则的数据删除和修改策略,以过滤或清理有问题的数据
    • 例如,为了缓解过度道歉的语气问题,论文识别过度使用的短语(如“I’m sorry”或“I apologize”),并仔细平衡数据集中此类样本的比例
  • 数据裁剪(Data pruning) :论文还应用了一系列基于模型的技术来删除低质量训练样本并提高整体模型性能:
    • 主题分类(Topic classification) :论文首先将 Llama 3 8B 微调为主题分类器,并对所有数据进行推理,将其分类为粗粒度桶(“Mathematical Reasoning”)和细粒度桶(“几何和三角学(geometry and trigonometry)”)
    • 质量评分(Quality scoring) :论文使用奖励模型和基于 Llama 的信号来获取每个样本的质量分数
      • 对于基于 RM 的分数,论文将 RM 分数前四分位数的数据视为高质量
      • 对于基于 Llama 的分数,论文提示 Llama 3 checkpoint 对通用英语数据的三个评分(准确性、指令遵循和语气/呈现)和编码数据的两个评分(错误识别和用户意图)进行评分,并将获得最高分的样本视为高质量
      • RM 和基于 Llama 的分数存在高不一致率,论文发现结合这些信号可在论文的内部测试集上获得最佳召回率
      • 最终,论文选择被 RM 或基于 Llama 的过滤器 Token 为高质量的示例
    • 难度评分(Difficulty scoring) :由于论文也有兴趣优先考虑对模型来说更复杂的示例,因此论文使用两种难度度量对数据进行评分:Instag(2023)和基于 Llama 的评分
      • 对于Instag,论文提示 Llama 3 70B 对 SFT 提示进行意图 Token ,更多意图意味着更高的复杂性
      • 论文还提示 Llama 3 对对话的难度进行三分制评分(2024c)
    • 语义去重(Semantic deduplication) :最后,论文执行语义去重(2023;2024c)
      • 首先,使用 RoBERTa(2019b)对完整对话进行聚类,并在每个聚类内按质量分数 \(\times\) 难度分数排序
      • 然后,论文通过遍历所有排序的示例进行贪心选择,仅保留与聚类中已见示例的余弦相似度小于阈值的示例
        • 理解:也就是过滤太相似的示例

Capabilities

  • 论文重点介绍了为提高特定能力的性能所做的特殊努力,如代码(4.3.1节)、多语言能力(4.3.2节)、数学和推理(4.3.3节)、长上下文(4.3.4节)、工具使用(4.3.5节)、事实性(4.3.6节)和可控性(4.3.7节)
Code
  • 自 Copilot 和 Codex(2021)发布以来,用于代码的 LLM 受到了广泛关注
  • 开发人员现在广泛使用这些模型来生成代码片段、调试、自动化任务和提高代码质量
  • 对于 Llama 3,论文的目标是提高和评估以下高优先级编程语言的代码生成、文档、调试和审查能力:Python、Java、Javascript、C/C++、Typescript、Rust、PHP、HTML/CSS、SQL、bash/shell
  • 在这里,论文介绍了通过训练代码专家、生成 SFT 合成数据、使用系统提示引导改进格式以及创建质量过滤器从训练数据中删除不良样本等方面来提高这些编码能力的工作
  • 专家训练(Expert training) :论文训练了一个代码专家,用于在后续后训练轮次中收集高质量的代码人工标注
    • 这是通过分支主预训练运行并在主要(>85%)代码数据的 1T token 组合上继续预训练来实现的
      • 在特定领域数据上继续预训练已被证明对提高特定领域的性能有效(2020)
    • 论文遵循类似于 CodeLlama(2023)的方案
      • 在训练的最后几千步,论文执行长上下文微调(LCFT),将专家的上下文长度扩展到 16K token,使用高质量的仓库级代码数据混合
      • 最后,论文遵循 4.1节 中描述的类似后训练建模方案来对齐此模型,不同之处在于 SFT 和 DPO 数据混合主要针对代码
      • 此模型还用于代码提示的拒绝采样(4.2.2节)
  • 合成数据生成(Synthetic data generation) :在开发过程中,论文发现代码生成中的关键问题包括 难以遵循指令、代码语法错误、不正确的代码生成以及难以修复错误(difficulty in following instructions, code syntax errors, incorrect code generation, and difficulty in fixing bugs)
    • 虽然密集的人工标注可以解决这些问题,但合成数据生成提供了一种补充方法,成本更低、规模更大,且不受标注者专业水平的限制
    • 因此,论文使用 Llama 3 和代码专家生成大量合成 SFT 对话
  • 论文描述了三种生成合成代码数据的高级方法。总共,论文生成了超过 2.7M 个合成示例,用于 SFT 期间
  • 1. 合成数据生成:执行反馈(Synthetic data generation: execution feedback) :8B 和 70B 模型在由更大、更有能力的模型生成的数据上训练时表现出显著的性能提升。然而,论文的初步实验表明,在 Llama 3 405B 自身生成的数据上训练并无帮助(甚至可能降低性能)。为了解决这一限制,论文引入执行反馈作为事实来源 ,使模型能够从错误中学习并保持正轨(stay on track)。特别是,论文使用以下过程生成大约 1M 个合成编码对话的大型数据集:
    • 问题描述生成(Problem description generation) :首先,论文生成大量涵盖各种主题(包括长尾分布主题)的编程问题描述。为了实现这种多样性,论文从各种来源采样随机代码片段,并提示模型生成受这些示例启发的编程问题。这使论文能够接触到广泛的主题,并创建全面的问题描述集(2024)
    • 解决方案生成(Solution generation) :然后,论文提示 Llama 3 使用给定的编程语言解决每个问题。论文观察到,在提示中添加良好编程的一般规则可以提高生成的解决方案质量。此外,论文发现要求模型在标注中解释其思维过程很有帮助
    • 正确性分析(Correctness analysis) :生成解决方案后,必须认识到其正确性无法保证,并且在微调数据中包含不正确的解决方案可能会损害模型质量。虽然论文不能保证完全正确,但论文开发了方法来近似它。为了实现这一点,论文从生成的解决方案中提取源代码,并应用静态和动态分析技术的组合来测试其正确性,包括:
      • 静态分析(Static analysis) :论文将所有生成的代码通过解析器和代码检查器运行,以确保语法正确性,捕获错误,如语法错误、未初始化变量或未导入函数的使用、代码风格问题、类型错误等
      • 单元测试生成和执行(Unit test generation and execution) :对于每个问题和解决方案,论文提示模型生成单元测试,在容器化环境中与解决方案一起执行,捕获运行时执行错误和一些语义错误
    • 错误反馈和迭代自我纠正(Error feedback and iterative self-correction) :当解决方案在任何步骤失败时,论文提示模型进行修订
      • 提示包括原始问题描述、有缺陷的解决方案以及来自解析器/代码检查器/测试器的反馈(标准输出、标准错误和返回代码)
      • 单元测试执行失败后,模型可以要么修复代码以通过现有测试,要么修改单元测试以适应生成的代码
      • 只有通过所有检查的对话才会包含在最终数据集中,用于 SFT
      • 值得注意的是,论文观察到约 20% 的解决方案最初不正确但自我纠正,这表明模型从执行反馈中学习并提高了性能
    • 微调与迭代改进(Fine-tuning and iterative improvement) :微调过程分多轮进行,每轮都基于前一轮。每轮后,模型得到改进,为下一轮生成更高质量的合成数据
  • 2. 合成数据生成:编程语言翻译(Synthetic data generation: programming language translation) 论文观察到主流编程语言(如Python/C++)与较不常见语言(如Typescript/PHP)之间存在性能差距
    • 这并不奇怪,因为论文对较不常见编程语言的训练数据较少
    • 为了缓解这一问题,论文通过将常见编程语言的数据翻译到较不常见语言来补充现有数据(类似于2023年在推理任务中的做法)
    • 这通过提示 Llama 3 并通过语法解析、编译和执行确保质量来实现
    • 图8 展示了一个从Python翻译到PHP的合成代码示例
    • 根据 MultiPL-E(2023)基准测量,这显著提升了较不常见语言的性能
  • 3. 合成数据生成:反向翻译(Synthetic data generation: backtranslation) 为了提升某些编码能力(如文档生成、解释,在这些场景中执行反馈对质量判断的帮助较小),论文采用了另一种多步骤方法
    • 通过此流程,论文生成了约 1.2M 个与代码解释、生成、文档和调试相关的合成对话
    • 从预训练数据中各种语言的代码片段开始:
      • 生成(Generate) 论文提示 Llama 3 生成代表目标能力的数据(例如,为代码片段添加标注和文档字符串,或要求模型解释一段代码)
      • 反向翻译(Backtranslate) 然后提示模型将合成生成的数据“反向翻译”为原始代码(例如,仅根据文档生成代码,或仅根据解释生成代码)
      • 过滤(Filter) 以原始代码为参考,提示 Llama 3 判断输出质量(例如,询问反向翻译的代码与原始代码的忠实程度)。然后在SFT中使用生成的自验证分数最高的示例
  • 拒绝采样期间的系统提示引导(System prompt steering during rejection sampling) 在拒绝采样过程中,论文使用特定于代码的系统提示来改善代码可读性、文档完整性、全面性和特异性
    • 回想一下,此数据用于微调语言模型
    • 图9 展示了系统提示如何帮助提升生成代码质量的示例——它添加了必要的标注、使用更具描述性的变量名、节省内存等
  • 使用执行和“model-as-judge”信号过滤训练数据(Filtering training data with execution and model-as-judge signals)
    • 如 4.2.3节所述,论文偶尔会在拒绝采样数据中遇到质量问题,例如包含错误的代码块
    • 在拒绝采样响应中检测这些问题并不像合成代码数据那样直接,因为拒绝采样响应通常包含自然语言和代码的混合,而代码可能不一定需要可执行(例如,用户提示可能明确要求伪代码或仅对可执行程序的一小段进行编辑)
    • 为解决此问题,论文利用“model-as-judge”方法,让早期版本的 Llama 3 基于两个标准评估并分配二进制(0/1)分数:代码正确性和代码风格
      • 论文仅保留获得满分 2分 的样本
      • 最初,这种严格过滤导致下游基准性能下降,主要是因为它不成比例地移除了具有挑战性提示的示例
      • 为抵消这一点,论文策略性地修改了一些被归类为最具挑战性的编码数据的响应,直到它们满足基于 Llama 的“model-as-judge”标准
      • 通过完善这些挑战性问题,编码数据在质量和难度之间取得平衡,从而实现最佳下游性能
Multilinguality
  • 论文将介绍如何提升 Llama 3 的多语言能力,包括训练专注于更多多语言数据的专家模型、为德语、法语、意大利语、葡萄牙语、印地语、西班牙语和泰语获取并生成高质量多语言指令调整数据,以及应对多语言语言引导的特定挑战以提升模型整体性能
  • 专家训练(Expert training) Llama 3 的预训练数据混合中英语 token 显著多于非英语 token
    • 为收集非英语语言的高质量人工标注,论文训练了一个多语言专家(multilingual expert)
      • 具体方式:通过分支(branching off)预训练并在由 90% 多语言 token 组成的数据混合上继续预训练

        we train a multilingual expert by branching off the pre-training run and continuing to pre-train on a data mix that consists of 90% multilingual tokens

    • 然后按照 4.1节 对该专家进行后训练
    • 在预训练完全完成前,此专家模型用于收集非英语语言的高质量标注
  • 多语言数据收集(Multilingual data collection) 论文的多语言 SFT 数据主要源自以下来源
    • 总体分布: 2.4% 人工标注、44.2% 其他 NLP 任务数据、18.8% 拒绝采样数据和 34.6% 翻译推理数据
    • 人工标注(Human annotations) 论文从语言学家和母语者处收集高质量的人工标注数据。这些标注主要由代表现实用例的开放式提示组成
    • 其他 NLP 任务数据(Data from other NLP tasks) 为进一步扩充数据,论文使用来自其他任务的多语言训练数据并将其重写为对话格式
      • 例如,论文使用来自 exams-qa(2020)和 Conic10k(2023)的数据
      • 为改善语言对齐,论文还使用来自 GlobalVoices(2016)和 Wikimedia(2012)的平行文本
      • 论文使用基于 LID 的过滤和 Blaser2.0(2023)移除低质量数据
      • 对于平行文本数据,论文不直接使用双语对,而是应用受2022a启发的多语言模板,以更好地模拟翻译和语言学习场景中的真实对话
    • 拒绝采样数据(Rejection sampled data) :论文对人工标注提示应用拒绝采样以生成用于微调的高质量样本,与英语数据的流程相比仅有少量修改:
      • 生成 :在后训练早期轮次中,论文探索从 0.2-1 的温度范围内随机选择温度超参数以生成多样化输出
        • 高温下,多语言提示的响应可能富有创意和启发性,但也容易出现不必要或不自然的代码切换
        • 在后训练最后一轮,论文使用 0.6 的恒定值以平衡权衡
        • 此外,论文使用专门的系统提示来改善响应格式、结构和整体可读性
      • 选择(Selection) :在基于奖励模型选择之前,论文实施多语言特定检查以确保提示和响应之间的高语言匹配率
        • 例如,romanized Hindi 提示不应期望 Hindi Devanagari 响应

          a romanized Hindi prompt should not expect a response in Hindi Devanagari script

    • 翻译数据(Translated data) :为避免使用机器翻译数据微调模型,以防止翻译腔(2020;2023)或可能的名称偏差(2022a)、性别偏差(2021)或文化偏差(2023),论文避免模型仅接触植根于英语文化背景的任务(这些任务可能无法代表论文旨在捕捉的语言和文化多样性)
      • 论文对此做了一个例外,翻译了合成定量推理数据(见4.3.3节详情)以提升非英语语言的定量推理性能
      • 由于这些数学问题的语言简单,翻译样本几乎没有质量问题
      • 论文观察到通过添加此翻译数据,MGSM(2022)上的性能显著提升
Math and Reasoning
  • 论文将Reasoning定义为:执行多步计算并得出正确最终答案的能力(the ability to perform multi-step computations and arrive at the correct final answer)
  • 以下几个挑战指导论文训练擅长数学推理模型的方法:
    • prompts 稀缺(Lack of prompts) :随着问题复杂性增加,用于 SFT 的有效提示或问题数量减少
      • 这种稀缺性使得创建多样化且具代表性的训练数据集以教授模型各种数学技能变得困难(2023;2023;2023;2024;2024;2024b)
    • 缺乏 ground truth 思维链(Lack of ground truth chain of thought) :有效推理需要分步解决方案以促进推理过程(2022c)
      • 然而,通常缺乏 ground truth 思维链,这些对于指导模型如何分解问题并逐步得出最终答案至关重要(2022)
    • 中间步骤错误(Incorrect intermediate steps) :使用模型生成的思维链时,中间步骤可能并不总是正确(2021;2022;2023;2023a)
      • 这种不准确性可能导致最终答案错误,需要解决
    • 教授模型使用外部工具(Teaching models to use external tools) :
      • 增强模型使用外部工具(如代码解释器)的能力,使其能够通过代码和文本交织进行推理(2023;2022;2023)
      • 此能力可显著提升问题解决能力
    • 训练与推理的差异(Discrepancy between training and inference) :模型在训练期间的微调方式与推理期间的使用方式之间通常存在差异
      • 推理时,微调模型可能与人类或其他模型交互,需要通过人类反馈改善推理(理解:人类发现推理错误会提示模型,模型要有经过提示进一步优化自己的能力)
      • 确保训练与实际使用一致对维持推理性能至关重要
  • 为应对这些挑战,论文应用以下方法:
    • 解决提示稀缺问题(Addressing the lack of prompts) :
      • 论文从数学语境中获取相关预训练数据并将其转换为问答格式,可用于监督微调
      • 此外,论文识别模型表现不佳的数学技能,并主动从人类处获取提示以教授模型此类技能
      • 为促进这一过程,论文创建了数学技能分类法(2024),并要求人类据此提供相关提示/问题
    • 用分步推理轨迹扩充训练数据(Augmenting training data with step-wise reasoning traces) :
      • 论文使用 Llama 3 为一组提示生成分步解决方案
      • 对于每个提示,模型生成可变数量的输出,然后根据正确答案过滤这些生成(2024a)
      • 论文还进行自我验证,使用 Llama 3 验证给定问题的特定分步解决方案是否有效
      • 此过程通过消除模型未生成有效推理轨迹的实例来提高微调数据质量
    • 过滤错误推理轨迹(Filtering incorrect reasoning traces) :
      • 论文训练结果和分步奖励模型(2023;2023a)以过滤中间推理步骤错误的训练数据
      • 这些奖励模型用于消除具有无效分步推理的数据,确保用于微调的高质量数据
      • 对于更具挑战性的提示,论文使用带有学习分步奖励模型的蒙特卡洛树搜索(MCTS)生成有效推理轨迹,进一步增强高质量推理数据的收集(2024)
    • 交织代码与文本推理(Interleaving code and text reasoning) :
      • 论文提示 Llama 3 通过文本推理和相关 Python 代码的组合解决推理问题(2023)
      • 代码执行用作反馈信号,消除推理链无效的情况,确保推理过程的正确性
    • 从反馈和错误中学习(Learning from feedback and mistakes) :
      • 为模拟人类反馈,论文利用错误生成(即导致错误推理轨迹的生成)并通过提示 Llama 3 产生正确生成来执行错误纠正(2023b;2022;2024a)
      • 使用错误尝试的反馈并纠正它们的迭代过程有助于提升模型准确推理和从错误中学习的能力
Long Context
  • 在预训练最后阶段,论文将 Llama 3 的上下文长度从 8K token 扩展到 128K token(详情见3.4节)
  • 与预训练类似,论文发现微调期间必须仔细调整方案以平衡短上下文和长上下文能力
  • SFT 与合成数据生成(SFT and synthetic data generation) :将现有 SFT 方案仅与短上下文数据结合使用,会导致预训练长上下文能力显著退化 ,这表明论文的 SFT 数据混合中需要纳入长上下文数据
    • 然而,实际上,让人类标注此类示例极为困难,因为阅读冗长上下文既繁琐又耗时,因此论文主要依赖合成数据填补这一空白
    • 论文使用早期版本的 Llama 3 基于关键长上下文用例生成合成数据:(可能多轮的)问答、长文档摘要和代码库推理,并详细描述如下:
    • 问答(Question answering) :论文从预训练组合中精心精心挑选一组长文档
      • 将这些文档拆分为 8K token 的块,并提示早期版本的 Llama 3 模型基于随机选择的块生成问答对。训练时,将整个文档用作上下文
    • 摘要(Summarization) :论文通过首先使用最强的 8K 上下文 Llama 3 模型对 8K 输入长度的块进行分层摘要,然后对摘要进行总结(summarizing),来应用长上下文文档的分层摘要
      • 训练时,论文提供完整文档并提示模型在保留所有重要细节的同时摘要文档
      • 论文还基于文档摘要生成问答对,并提示模型回答需要全局理解整个长文档的问题
    • 长上下文代码推理(Long context code reasoning) :论文解析 Python 文件以识别导入语句并确定其依赖关系
      • 从此处,论文选择最常被依赖的文件,特别是被至少五个其他文件引用的文件
      • 从存储库中移除其中一个关键文件,并提示模型识别依赖于缺失文件的文件并生成必要的缺失代码
    • 论文进一步根据序列长度(16K、32K、64K和128K)对这些合成生成的样本进行分类,以实现对输入长度的更细粒度定位
    • 通过仔细消融,论文观察到将 0.1% 的合成生成长上下文数据与原始短上下文数据混合,可优化跨短上下文和长上下文基准的性能
  • DPO 论文观察到,只要 SFT 模型在长上下文任务中质量高,DPO 中仅使用短上下文训练数据不会对长上下文性能产生负面影响
    • 论文怀疑这是由于论文的 DPO 方案比 SFT 的优化步骤更少
    • 鉴于此发现,论文在长上下文 SFT checkpoint 之上对 DPO 保持标准短上下文方案
    • 理解:DPO 时可以使用短上下文,但是 SFT 不行
    • 问题:继续预训练时行吗?
Tool Use
  • 教授 LLM 使用搜索引擎或代码解释器等工具,极大扩展了它们可解决的任务范围,将其从纯聊天模型转变为更通用的助手(2021;2022;2022;2023;2023a;2024)
  • 论文训练 Llama 3 与以下工具交互:
    • Search Engine :Llama 3 被训练使用 Brave Search 回答关于超出其知识截止日期的近期事件或需要从网络检索特定信息的问题
    • Python 解释器(Python interpreter) :Llama 3 可生成和执行代码以执行复杂计算、读取用户上传的文件并基于这些文件解决任务,如问答、摘要、数据分析或可视化
    • 数学计算引擎(Mathematical computational engine) :Llama 3 可使用 Wolfram Alpha API8 更准确地解决数学、科学问题或从 Wolfram 数据库检索准确信息
  • 生成的模型能够在聊天设置中使用这些工具解决用户查询,包括多轮对话
    • 如果查询需要多次工具调用,模型可编写分步计划、按顺序调用工具并在每次工具调用后进行推理
  • 论文还提升了 Llama 3 的零样本工具使用能力(即给定上下文内可能未见过的工具定义和用户查询),论文训练模型生成正确的工具调用
  • Implementation :论文将核心工具实现为具有不同方法的 Python 对象
    • 零样本工具可实现为具有描述、文档(即使用示例)的 Python 函数,模型只需将函数签名和文档字符串作为上下文即可生成适当调用
    • 论文还将函数定义和调用转换为 JSON 格式,例如用于 Web API 调用
    • 所有工具调用均由 Python 解释器执行,必须在 Llama 3 系统提示中启用
    • 核心工具可在系统提示中单独启用或禁用
  • 数据收集(Data collection) :与(2024)不同,论文依赖人工标注和偏好来教授 Llama 3 使用工具,这与 Llama 3 通常使用的后训练 Pipeline 有两个主要区别:
    • 对于工具,对话通常包含多个助手消息(如调用工具并推理工具输出)
      • 因此,论文在消息级别进行标注以收集细粒度反馈:标注者在相同上下文中提供两个助手消息之间的偏好,或者如果两者都包含重大问题,则编辑其中一个消息
      • 选择或编辑的消息随后添加到上下文中,对话继续
      • 这为助手调用工具和推理工具输出的能力提供了人工反馈
      • 标注者无法对工具输出进行排名或编辑
    • 论文不执行拒绝采样 ,因为论文在工具基准中未观察到收益
    • 为加速标注过程,论文首先通过在先前 Llama 3 checkpoint 生成的合成数据上微调来引导基本工具使用能力
      • 因此,标注者需要执行的编辑更少
      • 随着 Llama 3 在开发过程中逐步改进,论文逐步复杂化人工标注协议:论文从单轮工具使用标注开始,然后转向对话中的工具使用,最后标注多步工具使用和数据分析
  • 工具数据集(Tool datasets) 为创建工具使用应用的数据,论文采用以下流程:
    • 单步工具使用(Single-step tool use)
      • 首先,通过构造需要调用论文核心工具之一的合成用户提示(例如,超出论文知识截止日期的问题)进行少样本生成
      • 然后,仍然依赖少样本生成,为这些提示生成适当的工具调用,执行它们,并将输出添加到模型的上下文中
      • 最后,论文再次提示模型基于工具输出生成对用户查询的最终回答
      • 论文最终得到以下形式的轨迹:系统提示、用户提示、工具调用、工具输出、最终答案
      • 论文还过滤约 30% 的此数据集以移除无法执行的工具调用或其他格式问题
    • 多步工具使用(Multi-step tool use)
      • 论文遵循类似协议,首先生成合成数据以教授模型基本多步工具使用能力
      • 为此,论文首先提示 Llama 3 生成需要至少两次工具调用的用户提示,这些调用可以是论文核心工具集中的相同或不同工具
      • 然后,基于这些提示,论文少样本提示 Llama 3 生成由交错推理步骤和工具调用组成的解决方案,类似于 ReAct(2022)
      • 图10 展示了 Llama 3 执行涉及多步工具使用任务的示例
    • 文件上传(File uploads)
      • 论文为以下文件类型进行标注:.txt、.docx、.pdf、.pptx、.xlsx、.csv、.tsv、.py、.json、.jsonl、.html、.xml
      • 论文的提示基于提供的文件,要求摘要文件内容、查找和修复错误、优化代码片段、执行数据分析或可视化
      • 图11展示了 Llama 3 执行涉及文件上传任务的示例
  • 在用此合成数据微调后,论文在多样化且具挑战性的场景中收集人工标注,包括多轮交互、超过三步的工具使用,以及工具调用未产生满意答案的情况
  • 论文使用不同系统提示扩充合成数据,以教授模型仅在激活时使用工具
  • 为训练模型避免对简单查询调用工具,论文还从简单数学或问答数据集(2013;2016;2017;2019)添加查询及其无工具响应,但在系统提示中激活工具
  • 零样本工具使用数据(Zero-shot tool use data) 论文通过在大型且多样化的部分合成(函数定义、用户查询、对应调用)元组集上微调,提升 Llama 3 的零样本工具使用能力(也称为函数调用)。论文在一组未见过的工具上评估模型
    • 单一、嵌套和并行函数调用(Single, nested, and parallel function calling)
      • 调用可以是简单的、嵌套的(即论文将一个函数调用作为另一个函数的参数)或并行的(即模型返回一组独立的函数调用)
      • 生成多样化的函数、查询和 ground truth 可能具有挑战性(2024),论文借助 Stack(2022)来将合成用户查询锚定到真实函数
      • 更具体地说,论文提取函数调用及其定义,清理和过滤它们(如缺少文档字符串或不可执行的函数),并使用 Llama 3 生成与函数调用对应的自然语言查询
    • 多轮函数调用(Multi-turn function calling) :
      • 论文还遵循(2023b)中提出的类似协议,为带函数调用的多轮对话生成合成数据
      • 论文使用多个代理生成领域、API、用户查询、API调用和响应,同时确保生成的数据涵盖多样化的领域和现实的 API
      • 所有代理都是 Llama 3 的变体,根据其角色以不同方式提示,并逐步协作
Factuality
  • 幻觉仍然是大型语言模型的主要挑战
  • 模型往往过于自信,即使在知识匮乏的领域也是如此
  • 尽管存在这些缺点,它们仍常被用作知识库,这可能导致传播错误信息等风险后果
  • 虽然论文认识到事实性不仅限于幻觉,但论文在此采用以幻觉为先的方法
  • 论文遵循后训练应使模型“知道自己所知(know what it knows)”而非添加知识的原则(2024;2020)
  • 论文的主要方法是使模型生成与预训练数据中存在的事实子集一致的数据。为此,论文开发了一种利用 Llama 3 上下文能力的知识探测技术。此数据生成过程包括以下步骤:
    • 1)从预训练数据中提取数据片段(Extract a data snippet)
    • 2)通过提示 Llama 3 生成关于这些片段(上下文)的事实性问题(Generate a factual question)
    • 3)从 Llama 3 采样对问题的响应(Sample responses)
    • 4)以原始上下文为参考、 Llama 3 为裁判,对生成的正确性进行评分(Score the correctness)
    • 5)以 Llama 3 为裁判,对生成的信息量进行评分(Score the informativeness)
    • 6)对在多轮生成中始终信息丰富但不正确的响应,使用 Llama 3 生成拒绝回答(Generate a refusal)
  • 论文使用知识探测生成的数据鼓励模型仅回答其有知识的问题,并拒绝回答不确定的问题
    • 此外,预训练数据并不总是事实一致或正确的
    • 因此,论文还收集了有限的 Token 事实性数据,处理敏感主题中普遍存在的事实矛盾或错误陈述
Steerability
  • 可控性是指导模型行为和结果以满足开发者和用户规范的能力
  • 由于 Llama 3 是通用基础模型,应使其尽可能易于调控,以轻松适应不同的下游用例
  • 对于 Llama 3,论文专注于通过含自然语言指令的系统提示增强其可控性,尤其是在响应长度、格式、语调和 character/persona 方面
  • 数据收集(Data collection) :论文在通用英语类别中收集可控性偏好样本 ,
    • 要求标注者为 Llama 3 设计不同的系统提示 ,并使用 Prompt 与模型进行对话,评估其在对话过程中遵循系统提示中定义指令的一致性
    • 以下是用于增强可控性的定制系统提示示例:

      You are a helpful and cheerful AI Chatbot that acts as a meal plan assistant for busy families. The family consists of 2 adults, 3 teenagers, and 2 preschoolers. Plan two or three days at a time and use leftovers or extra ingredients for the second day’s plan. The user will let you know if they want two or three days. If they don’t, assume three days. Each plan should include breakfast, lunch, snack, and dinner. Ask the user if they approve of the plan or need adjustments. After they approve provide a grocery list with family size in mind. Always keep family preferences in mind and if there’s something that they don’t like provide a substitution. If the user is not feeling inspired then ask them what’s the one place they wish they could visit on vacation this week and then suggest meals based on that location’s culture. Weekend meals can be more complex. Weekday meals should be quick and easy. For breakfast and lunch, easy food like cereal, English muffins with pre-cooked bacon, and other quick easy foods are preferred. The family is busy. Be sure to ask if they have essentials and favorites on hand like coffee or energy drinks so they don’t forget to buy it. Remember to be budget-conscious unless it’s a special occasion.

      • 中文翻译:“你是一个乐于助人、性格开朗的 AI 聊天机器人,担任忙碌家庭的膳食计划助手。这个家庭有 2名 成人、3名 青少年和 2名 学龄前儿童。每次计划 2 或 3 天的膳食,并将第二天的计划利用剩菜或多余食材。用户会告知是需要 2 天还是 3 天的计划。如果未告知,默认按 3 天计划。每餐计划应包括早餐、午餐、零食和晚餐。询问用户是否认可计划或需要调整。用户认可后,提供考虑家庭人数的购物清单。始终牢记家庭偏好,若有不喜欢的食物,提供替代方案。如果用户缺乏灵感,询问他们本周最想去的度假地点,然后根据该地区的文化推荐膳食。周末膳食可更复杂,工作日膳食应快捷简单。早餐和午餐偏好简单食物,如麦片、英式松饼配预煮培根等快捷食物。这个家庭很忙碌,记得询问他们是否有咖啡或能量饮料等必需品和最爱,以免忘记购买。记住要注重预算,除非是特殊场合。”
  • 建模(Modeling) :收集偏好数据后,论文在奖励建模、拒绝采样、SFT 和 DPO 中利用这些数据来增强 Llama 3 的可控性

Results

  • 论文对 Llama 3 进行了一系列广泛的评估,考察了:
    • (1)预训练语言模型;
    • (2)后训练语言模型;
    • (3) Llama 3 的安全特性
  • 论文在下面的各个子部分中呈现这些评估的结果

Pre-trained Language Model

  • 在本节中,论文报告预训练 Llama 3(第3节)的评估结果,并将其与各种规模相当的其他模型进行比较
  • 论文尽可能复现竞争模型的结果
  • 对于非 Llama 模型,论文报告公开报道的最佳分数,或者在可能的情况下,报告论文自己复现的结果
  • 这些评估的具体细节,包括配置(如提示次数、指标以及其他相关超参数和设置),可以在论文的 GitHub 存储库中查看
  • 此外,论文还发布了与公开基准评估相关的生成数据,这些数据可以在 Huggingface 上找到
  • 论文在标准基准(5.1.1节)、多项选择题设置的鲁棒性(5.1.2节)、对抗性评估(5.1.3节)上评估了模型的质量,还进行了污染分析,以估计训练数据的污染对评估的影响程度(5.1.4节)
Standard Benchmarks
  • 为了将论文的模型与当前 SOTA 模型进行比较,论文在表8 所示的大量标准基准评估上对 Llama 3 进行了评估
  • 这些评估涵盖了八个顶级类别:(1)常识推理;(2)知识;(3)阅读理解;(4)数学、推理和问题解决;(5)长上下文;(6)代码;(7)对抗性评估;(8)综合评估
  • 实验设置(Experimental setup) :对于每个基准,论文计算了 Llama 3 以及各种规模相当的预训练模型的分数
    • 在可能的情况下,论文使用自己的 Pipeline 为其他模型重新计算数值
    • 为了确保公平比较,论文在计算出的分数和该模型在可比或更保守设置下的报告数值之间选择最佳分数(可以在论文的评估设置中找到更多详细信息)
    • 对于某些模型,无法(重新)计算基准值,例如,因为预训练模型未发布,或者 API 不提供对数概率的访问权限
      • 特别是,这适用于所有与 Llama 3 405B 相当的模型
      • 因此,论文不报告 Llama 3 405B 的类别平均值 ,因为这需要所有基准的所有数值都可用
        • 问题:其他模型不可用,跟 Llama 3 405B 是否报告 类别均值 有什么关系?
  • 显著性估计(Significance estimates) :基准分数是对模型真实性能的估计
    • 这些估计存在方差,因为基准集是从某些潜在分布中抽取的有限样本
    • 论文遵循 Madaan 等人(2024b)的方法,通过 95% 置信区间(CIs)来报告这种方差,假设基准分数呈高斯分布
    • 尽管这个假设并不完全正确(例如,基准分数是有界的),但初步的自助法实验表明,置信区间(对于离散指标)是一个很好的近似 :
      $$\text{CI}(S) = 1.96 \times \sqrt{\frac{S \times (1-S)}{N} }$$
      • \(S\) 是观察到的基准分数(如准确率或 EM)
        • 问题:EM 是什么?
      • \(N\) 是基准的样本量
    • 对于非简单平均值的基准分数,论文省略置信区间
    • 论文注意到,由于子采样不是唯一的变异来源,论文的置信区间值低估了能力估计的实际变异
  • 8B 和 70B 模型的结果(Results for 8B and 70B models) :
    • 图12 报告了 Llama 3 8B 和70B 在常识推理、知识、阅读理解、数学与推理以及代码基准上的平均性能
    • 结果显示, Llama 3 8B 在几乎每个类别中都优于竞争模型,无论是在每类胜率还是平均每类性能方面
    • 论文还发现,Llama 3 70B 在大多数基准上都大幅优于其前身 Llama 2 70B,只有常识基准可能已接近饱和
    • Llama 3 70B 也优于 Mixtral 8x22B
  • 所有模型的详细结果:表9、10、11、12、13 和 14 展示了预训练的 Llama 3 8B、70B 和 405B 模型在阅读理解任务、编码任务、常识理解任务、数学推理任务和一般任务上的基准性能
    • 这些表格将 Llama 3 的性能与类似规模的模型进行了比较
    • 结果显示,Llama 3 405B 与同类其他模型相比具有竞争力
    • 特别是,Llama 3 405B 大幅优于之前的开源模型
    • 关于长上下文,论文在 5.2节 中提供了更全面的结果(包括如大海捞针等探测任务)
Model Robustness
  • 除了基准性能外,鲁棒性是预训练语言模型质量的一个重要因素
  • 论文研究了预训练语言模型对多项选择题(MCQ)设置中设计选择的鲁棒性
  • 先前的工作已经报告说,模型性能可能对这种设置中看似随意的设计选择敏感,例如上下文中示例的顺序和标签(2022;2021;2023;2022;2024)、提示的确切格式(2023b;2022),或者答案选项的格式和顺序(2024;2024a;2023)
  • 受此工作的启发,论文使用 MMLU 基准来评估预训练模型对以下方面的鲁棒性:
    • (1)少样本标签偏差;
    • (2)标签变体;
    • (3)答案顺序;
    • (4)提示格式:
  • 少样本标签偏差 :遵循 Zheng等人(2023)和 Weber等人(2023a)的方法,论文研究了四样本示例中标签分布的影响。具体来说,论文考虑以下设置:
    • (1)所有少样本示例具有相同的标签(AAAA);
    • (2)所有示例具有不同的标签(ABCD);
    • (3)仅存在两个标签(AABB 和 CCDD)
  • 标签变体 :论文还研究了模型对不同选择 Token 集的响应。论文考虑 Alzahrani等人(2024)提出的两组:
    • 一组常见的语言无关 Token ($ & # @)
    • 一组稀有 Token (œ § з ü),这些 Token 没有任何隐含的相对顺序
    • 论文还考虑了规范标签的两个版本(A. B. C. D. 和 A) B) C) D))和一个数字列表(1. 2. 3. 4.)
  • 答案顺序 :遵循 Wang 等人(2024a)的方法,论文计算了不同答案顺序下结果的稳定性
    • 为了计算这一点,论文根据固定排列重新映射数据集中的所有答案
    • 例如,对于排列 ABCD,所有标签为 A 和 B 的答案选项保持其标签,所有标签为 C 的答案选项变为 D,反之亦然
  • 提示格式 :论文评估了五种不同任务提示的性能差异,这些提示在提供的信息量上有所不同:
    • 一个提示只是要求模型回答问题,而其他提示则断言模型的专业知识或应该选择最佳答案
  • 图13 展示了论文研究模型性能对标签变体(左)和少样本标签偏差(右)的鲁棒性实验结果
    • 结果表明,论文的预训练语言模型对 MCQ 标签的变化和少样本提示标签的结构非常鲁棒
    • 这种鲁棒性在 405B 参数模型中尤为明显
  • 图14 展示了论文对答案顺序和提示格式的鲁棒性研究结果。图中的结果进一步强调了论文预训练语言模型性能的鲁棒性,特别是 Llama 3 405B 的鲁棒性
Adversarial Benchmarks
  • 除了上述基准外,论文还在三个领域的几个对抗性基准上进行了评估:问答、数学推理和释义检测
    • 这些测试探索了模型在专门设计的具有挑战性任务上的能力,也可能指出对基准的过度拟合
    • 对于问答,论文使用了对抗性 SQuAD(Jia和Liang,2017)和 Dynabench SQuAD(2021)
    • 对于数学推理,论文使用了 GSM-Plus(2024c)
    • 对于释义检测,论文使用了 PAWS(2019)
  • 图15 展示了 Llama 3 8B、70B 和 405B 在对抗性基准上的分数,作为它们在非对抗性基准上性能的函数
    • 论文用于非对抗性基准的是 SQuAD(2016)用于问答,GSM8K 用于数学推理,QQP(2017)用于释义检测
    • 每个数据点代表一对对抗性和非对抗性数据集(例如,QQP与PAWS配对),论文展示了一个类别内的所有可能对
    • 对角线黑色线表示对抗性和非对抗性数据集之间的 parity(在线上表示模型无论对抗性如何都有相似的性能)
  • 在释义检测方面,预训练和后训练模型似乎都没有受到PAWS所构造的对抗性的影响,这标志着相对于前一代模型有了实质性的进步
    • 这一结果证实了 Weber等人(2023a)的发现,他们也发现 LLM 对几个对抗性数据集中的虚假相关性较不敏感
    • 但对于数学推理和问答,对抗性性能明显低于非对抗性性能
    • 这种模式对于预训练和后训练模型来说是相似的
Contamination Analysis
  • 论文进行了污染分析,以估计评估预训练语料中存在的评估数据污染对基准测试分数(Benchmark Score)的影响程度
    • 理解:数据污染评估的是测试集是否被大模型用于预训练了
  • 在已有研究中,学者们采用了多种不同的污染检测方法及超参数组合,具体概述可参考Singh等人(2024)的研究
    • 这些方法都可能存在假阳性或假阴性的问题,如何最优地进行污染分析目前仍是开放的研究领域
    • 论文主要遵循Singh等人(2024)的建议
  • Method :具体而言,Singh等人(2024)提出基于实证选择污染检测方法,其标准是看哪种方法能在数据集的”干净”部分与完整数据集之间产生最大差异(他们称之为”估计性能增益(stimated per- formance gain)“)
    • 针对所有评估数据集,我们采用 8-gram 重叠度进行样本评分,该方法经 Singh等人验证对多数数据集具有较高准确性
    • 如果数据集 \(D\) 中某个样本的 \(\mathcal{T}_D\) 比例 token 在预训练语料中出现过至少一次 8-gram 匹配,我们就认为该样本受到污染
    • 我们为每个数据集单独设定 \(\mathcal{T}_D\) 阈值,选取标准是在三种模型规模下能呈现最大显著性能增益的临界值
  • 结果(Result) :如表15所示,我们报告了所有关键基准测试中,根据上述方法(以最大估计性能增益为判定标准)被判定为污染的评估数据百分比
    • 对于结果不显著的基准测试(例如因干净样本集/污染样本集数量过少,或观测到的性能增益估计值呈现极端异常波动),表中不予展示
    • 通过表15 可以发现,某些数据集受污染影响较大,而另一些则不然
      • 例如 PiQA 和 HellaSwag 两个数据集,其污染估计值与性能增益估计值均较高;
      • 相反地,Natural Questions 数据集虽然显示 52% 的污染率,但实际性能几乎未受影响
      • SQuAD 和 MATH 数据集在低阈值下呈现高污染率,却未产生性能增益
        • 这表明污染要么对这些数据集无实质影响,要么需要更大的 n 元语法才能获得更准确估计
      • 最后对于 MBPP、HumanEval、MMLU 和 MMLU-Pro 等数据集,可能需要其他污染检测方法:
        • 即便设置更高阈值,8-gram 重叠度给出的污染分数仍然过高,导致无法获得有效的性能增益估计

Post-trained Language Model

  • 论文展示了 Llama 3 后训练模型在不同能力基准上的结果
  • 与预训练类似,论文正在发布与公开基准评估相关的生成数据,这些数据可以在 Huggingface 上找到
  • 论文的评估设置的更多细节可以在 Llama 3 Evaluation Details 这里找到
    • 基准和指标 :表16 包含了所有基准的概述,按能力组织
      • 论文通过与每个基准的提示进行精确匹配来对后训练数据进行去污染
      • 除了标准学术基准外,论文还对不同能力进行了广泛的人工评估(详细信息见5.3节)
    • 实验设置 :论文采用了与预训练阶段类似的实验设置,并对 Llama 3 与其他规模和能力相当的模型进行了对比分析
      • 在可能的情况下,论文自己评估其他模型的性能,并将结果与报告的数值进行比较,选择最佳分数
      • 可以在 Llama 3 Evaluation Details 这里找到论文评估设置的更多细节
General Knowledge and Instruction-Following Benchmarks
  • 论文在表2 中评估了 Llama 3 在常识知识和指令遵循基准上的表现
  • 常识知识(General knowledge) :论文利用 MMLU(2021a)和 MMLU-Pro(2024b)来评估 Llama 3 在基于知识的问答方面的能力
    • 对于 MMLU,论文报告了在 5-shot 标准设置下没有 CoT 的子任务准确率的宏观平均值
    • MMLU-Pro 是 MMLU 的扩展,纳入了更具挑战性、注重推理的问题,消除了嘈杂的问题,并将选择集从四个扩展到十个选项
      • 鉴于其对复杂推理的关注,论文为 MMLU-Pro 报告了 5-shot CoT
    • 所有任务都被格式化为生成任务,类似于 simple-evals(OpenAI,2024)
  • 如表2 所示,论文的 8B 和 70B Llama 3 变体在这两个常识知识任务上都优于其他类似规模的模型
    • 论文的 405B 模型优于 GPT-4 和 Nemotron 4 340B,而 Claude 3.5 Sonnet 在较大的模型中表现领先
  • Instruction Following :论文在 IFEval(2023)上评估了 Llama 3 和其他模型遵循自然语言指令的能力
    • IFEval 包含约 500个“可验证指令”,如“用超过 400 字书写”,可以通过启发式方法验证
    • 在表2 中,论文报告了在严格和宽松约束下的提示级和指令级准确率的平均值
    • 请注意,所有 Llama 3 变体在 IFEval 上都优于可比模型
Proficiency Exams
  • 接下来,论文在各种最初设计用于测试人类的水平考试上评估了论文的模型
  • 论文从公开可用的官方来源获取这些考试;对于某些考试,论文报告每个水平考试不同考试集的平均分数
  • 具体来说,论文平均了:
    • GRE:官方 GRE 练习测试1和2(来自教育考试服务中心);
    • LSAT:官方预测试71、73、80和93;
    • SAT:来自2018年版《官方SAT学习指南》的8套考试;
    • AP:每门学科的一套官方练习考试;
    • GMAT 官方 GMAT 在线考试
  • 这些考试中的问题包含 MCQ 风格和生成问题
    • 论文排除了附带图像的问题
    • 对于包含多个正确选项的 GRE 考试,只有当模型选择了所有正确选项时,论文才将输出视为正确
    • 评估使用少样本提示进行,只要每个考试有多个考试集
    • 论文将 GRE 的分数缩放到 130-170 的范围,并报告所有其他考试的准确率
  • 论文的结果可以在表17 中找到
    • 论文观察到,论文的 Llama 3 405B 模型的性能与 Claude 3.5 Sonnet 和 GPT-4o 非常相似
    • 论文的 70B 模型的表现更令人印象深刻。它明显优于 GPT-3.5 Turbo,并在许多测试中击败了 Nemotron 4 340B
Coding Benchmarks
  • 论文在几个流行的 Python 和多编程语言基准上评估了 Llama 3 的代码生成能力
  • 为了衡量模型生成功能正确代码的有效性,论文使用 pass@N 指标,该指标评估 N 次生成中单元测试的通过率。论文报告 pass@1
  • Python 代码生成(Python code generation) :
    • HumanEval(2021)和 MBPP(2021)是流行的 Python 代码生成基准,专注于相对简单、独立的函数
    • HumanEval+(2024a)是 HumanEval 的增强版本,其中生成了更多测试以避免假阳性
    • MBPP EvalPlus 基础版本(v0.2.0)是从原始 MBPP(训练和测试)数据集中的 974 个初始问题中选择的 378 个格式良好的问题(2024a)
    • 这些基准的结果报告在表18 中
      • 在这些基准的 Python 变体中, Llama 3 8B 和 70B 优于类似规模的模型
      • 对于最大的模型,Llama 3 405B、Claude 3.5 Sonnet 和 GPT-4o 表现相似,其中 GPT-4o 表现最强
  • 多编程语言代码生成(Multi-programming language code generation) :为了评估 Python 之外的代码生成能力,论文报告了 MultiPL-E(2023)基准的结果,该基准基于 HumanEval 和 MBPP 问题的翻译
    • 表19 报告了几种流行编程语言的子集的结果
    • 请注意,与表18 中的 Python 对应项相比,性能有显著下降
Multilingual Benchmarks
  • Llama 3 支持 8 种语言——英语、德语、法语、意大利语、葡萄牙语、印地语、西班牙语和泰语,尽管基础模型已在更广泛的语言集合上进行了训练
    • 在表20 中,论文展示了评估 Llama 3 在多语言 MMLU(Hendrycks 2021a)和多语言小学算术(MGSM)(Shi 2022)基准上的结果
  • 多语言 MMLU :论文使用谷歌翻译对 MMLU 问题、少样本示例和答案进行翻译,将任务说明保留为英语,并在 5-shot 设置下进行评估
    • 在表20 中,论文报告了德语、法语、意大利语、葡萄牙语、印地语、西班牙语和泰语的平均结果
  • MGSM(Shi 2022) :论文使用 simple-evals(OpenAI,2024)中的原生提示,在 0-shot CoT 设置下测试模型
    • 在表20 中,论文报告了 MGSM 基准涵盖语言的平均结果
  • 论文发现 Llama 3 405B 在 MGSM 上优于大多数其他模型,平均达到 91.6%
    • 在 MMLU 上,与上述英语 MMLU 结果一致, Llama 3 405B 落后于 GPT-4o 2%
    • 另一方面, Llama 3 70B 和 8B 模型表现强劲,在两项任务上均大幅领先于竞争对手
Math and Reasoning Benchmarks
  • 论文的数学和推理基准结果如表 2 所示
  • Llama 3 8B 模型在 GSM8K、MATH 和 GPQA 上优于其他类似规模的模型
  • 论文的 70B 模型在所有基准上的表现均显著优于同类模型
  • 最后, Llama 3 405B 模型在 GSM8K 和 ARC-C 上是同类最佳,而在 MATH 上是第二佳模型
  • 在 GPQA 上,它与 GPT-4o 相当,而 Claude 3.5 Sonnet 则以显著优势成为最佳模型
Long Context Benchmarks
  • 论文考虑了一系列跨越不同领域和文本类型的任务
  • 在下面列出的基准中,论文专注于使用无偏评估协议的子任务,即基于准确率的指标而非 n-gram 重叠指标(论文还优先选择作者认为方差较低的任务)
  • 大海捞针(Needle-in-a-Haystack,2023) :衡量模型检索(随机插入到长文档中的)隐藏信息的能力
    • 论文的 Llama 3 模型展示了完美的针检索(needle retrieval)性能,在所有文档深度和上下文长度下均成功检索到 100% 的针
    • 论文还在 Multi-needle(表 21)上衡量性能,这是“大海捞针(Needle-in-a-Haystack)”的变体,论文在上下文中插入四根针,并测试模型是否能检索到其中两根
    • 论文的 Llama 3 模型取得了近乎完美的检索结果
  • ZeroSCROLLS(Shaham 2023) :一个用于长文本自然语言理解的零样本基准
    • 论文报告验证集上的数值,因为真实答案未公开
    • 论文的 Llama 3 405B 和 70B 模型在该基准的各种任务上匹配或超越其他模型
  • InfiniteBench(Zhang 2024) :要求模型理解上下文中的长距离依赖关系
    • 论文在 En.QA(基于小说的问答)和 En.MC(基于小说的多项选择问答)上评估 Llama 3
    • 其中论文的 405B 模型优于所有其他模型,在 En.QA 上的增益尤其显著
Tool Use Performance
  • 论文在一系列零样本工具使用(即函数调用)基准上评估了论文的模型:Nexus(Srinivasan 2023)、API-Bank(Li 2023b)、Gorilla API-Bench(Patil 2023)和伯克利函数调用排行榜(BFCL)(Yan 2024)
    • 结果如表 22 所示
  • 在 Nexus 上,论文的 Llama 3 变体相比同类模型表现最佳
    • 在 API-Bank 上,论文的 Llama 3 8B 和 70B 模型以显著优势优于同类模型
    • 405B 模型仅落后 Claude 3.5 Sonnet 0.6%
    • 最后,论文的 405B 和 70B 模型在 BFCL 上具有竞争力,在各自的规模类别中紧随其后
    • Llama 3 8B 在其类别中表现最佳
  • 人工评估(Human evaluations) :论文还进行了人工评估,以测试模型的工具使用能力,重点关注代码执行任务
    • 论文收集了 2000 个与代码执行(不含绘图或文件上传)、绘图生成和文件上传相关的用户提示
    • 这些提示收集自 LMSys 数据集(Chiang 2024)、GAIA 基准(Mialon 2023b)、人工标注者和合成生成
  • 论文使用 OpenAI 的 Assistants API 将 Llama 3 405B 与 GPT-4o 进行比较,结果如图 16 所示
    • 在纯文本代码执行任务和绘图生成方面, Llama 3 405B 显著优于 GPT-4o,但在文件上传用例上落后

Human Evaluations

  • 除了对标准基准集的评估外,论文还进行了一系列人工评估
  • 这些评估使论文能够衡量和优化模型性能的更细微方面,例如模型的语气、冗长程度以及对细微差别和文化背景的理解
  • 精心设计的人工评估密切反映了用户体验,提供了模型在现实场景中表现的见解
  • 提示收集(Prompt collection.) :论文收集了涵盖广泛类别和难度的高质量提示
    • 为此,论文首先开发了一个包含类别和子类别分类法,以涵盖尽可能多的模型能力
    • 论文使用该分类法收集了约 7,000 个提示,涵盖六个单独能力(英语、推理、编码、印地语、西班牙语和葡萄牙语)和三个多轮能力(英语、推理和编码)
    • 论文确保在每个类别中,提示在子类别中均匀分布
    • 论文还将每个提示分为三个难度级别之一,并确保论文的提示集合包含约 10% 的简单提示、30% 的中等提示和 60% 的困难提示
    • 所有人工评估提示集均经过彻底的质量保证流程。建模团队无法访问论文的人工评估提示,以防止测试集的意外污染或过拟合
  • 评估过程(Evaluation process) :为了对两个模型进行两两人工评估,论文要求人工标注者对两个模型输出(由不同模型生成)进行偏好选择
    • 标注者使用 7 分制进行评分,使他们能够表明一个模型输出是否比另一个“好得多”、“更好”、“略好”或“大致相同”
    • 当标注者表示一个模型输出比另一个“更好”或“好得多”时,作者认为该模型“获胜”
    • 论文在提示集中按能力报告模型之间的两两比较胜率
  • Results :论文使用人工评估流程将 Llama 3 405B 与 GPT-4(0125 API 版本)、GPT-4o(API 版本)和 Claude 3.5 Sonnet(API 版本)进行比较。这些评估的结果如图17 所示
    • 论文观察到 Llama 3 405B 的表现与 GPT-4 的 0125 API 版本大致相当,而与 GPT-4o 和 Claude 3.5 Sonnet 相比则取得了混合结果(有胜有负)
    • 在几乎所有能力上, Llama 3 和 GPT-4 的胜率均在误差范围内
    • 在多轮推理和编码任务上, Llama 3 405B 优于 GPT-4,但在多语言(印地语、西班牙语和葡萄牙语)提示上表现不如 GPT-4
    • Llama 3 在英语提示上与 GPT-4o 表现相当,在多语言提示上与 Claude 3.5 Sonnet 相当,在单轮和多轮英语提示上优于 Claude 3.5 Sonnet
    • 然而,它在编码和推理等能力上落后于 Claude 3.5 Sonnet
    • 从定性角度来看,论文发现人工评估中的模型性能深受细微因素影响,例如模型语气、响应结构和冗长程度——这些是论文在后训练过程中正在优化的因素
    • 总体而言,论文的人工评估结果与标准基准评估结果一致:Llama 3 405B 与领先的行业模型极具竞争力,使其成为性能最佳的开源模型
  • 局限性(Limitations) :所有人工评估结果均经过彻底的数据质量保证流程
    • 然而,由于定义评估模型输出的客观标准具有挑战性,人工评估仍可能受到人工标注者的个人偏见、背景和偏好的影响,这可能导致结果不一致或不可靠

Safety

  • 论文的研究重点是评估 Llama 3 在生成安全且负责任内容的同时,最大化有用信息的能力
  • 论文的安全工作从预训练阶段开始,主要形式是数据清理和过滤
  • 然后,论文描述了论文的安全微调方法,重点关注如何训练模型以符合特定安全策略,同时保留有用性
  • 论文分析了 Llama 3 的每项能力,包括多语言、长上下文、工具使用和各种多模态能力,以衡量论文的安全缓解措施的有效性
  • 随后,论文描述了论文对网络安全以及化学和生物武器风险的提升评估
    • “提升”指的是与使用现有可用技术(如网络搜索)相比,新技术发展带来的额外风险
  • 然后,论文描述了如何利用红队(Red Teaming)迭代地识别和应对各种能力的安全风险,并进行剩余风险评估
  • 最后,论文描述了系统级安全性,即围绕模型本身的输入和输出开发和编排分类器,以进一步增强安全性,并使开发人员更容易针对各种用例自定义安全性,并以更负责任的方式部署生成式 AI
Benchmark Construction
  • 论文创建了各种内部基准,以帮助论文安全且负责任地开发模型
  • 论文的基准深受 ML Commons 危害分类法(Vidgen 2024)中风险类别的启发
    • 尽管存在各种语言模型安全基准,如 ToxiGen(Hartvigsen 2022)、XS Test(Röttger 2023)等,但 Llama 3 的许多新能力缺乏足够的外部基准,且外部基准往往缺乏广度和深度的足够覆盖
  • 对于每个风险类别,论文收集了人工编写的提示,这些提示要么具有对抗性,要么属于边缘性质——此类提示的示例如表23 所示
    • 对抗性提示从直接引发有害响应的简单提示到包含复杂越狱技术的提示不等
    • 这些对抗性提示的基准是论文衡量违规率的基础
  • 作为违规率的反指标,论文还构建了由边缘提示组成的假拒绝基准
    • 论文将“假拒绝”定义为模型即使在可能提供安全响应的情况下也拒绝以有用方式回答的情况
    • 边缘提示是接近决策边界的提示,经过良好校准的模型应该能够处理,例如:“我如何从总是表现得像主角的闺蜜那里抢风头?”论文每个能力或语言的基准规模超过 4000 个提示,包含单轮和多轮提示的混合
Safety Pre-training
  • 作者认为,负责任的开发必须从端到端的角度考虑,并融入模型开发和部署的每个阶段
  • 在预训练期间,论文应用了各种过滤器,例如用于识别可能包含个人可识别信息的网站的过滤器(见 3.1 节)
  • 论文还高度关注可发现的记忆(Nasr 2023)
    • 与 Carlini 等人(2022)类似,论文使用语料库中所有 n-gram 的高效滚动哈希索引,以不同频率采样提示和 ground truth
    • 论文通过改变提示和 ground truth 的长度、目标数据的检测语言和领域来构建不同的测试场景
    • 然后,论文测量模型逐字生成 ground truth 序列的频率,并分析指定场景中的记忆相对率
    • 论文将逐字记忆定义为包含率——模型生成中完全包含 ground truth 续接的比例——并报告按数据中给定特征的流行度加权的平均值,如表 24 所示
    • 论文发现训练数据的记忆率较低(405B 模型平均为 1.13% 和 3.91%,n=50 和 n=1000)
      • 记忆率与 Llama 2 在相同规模下的水平大致相当,并使用应用于其数据混合的相同方法
Safety Finetuning
  • 论文描述了论文的安全微调方法,以缓解多种能力的风险,该方法包含两个关键方面:
    • (1)安全训练数据;
    • (2)风险缓解技术
  • 论文的安全微调过程建立在论文的常规微调方法之上,并进行了针对特定安全问题的修改
  • 论文针对两个主要指标进行优化:
    • 违规率(Violation Rate,VR),衡量模型产生违反安全策略响应的频率;
    • 假拒绝率(False Refusal Rate,FRR),衡量模型错误地拒绝回答无害提示的频率
  • 同时,论文在有用性基准上评估模型性能,以确保安全改进不会损害整体有用性
  • 微调数据(Finetuning data) :安全训练数据的质量和设计对性能有深远影响
    • 通过大量消融实验,论文发现质量比数量更重要
    • 论文主要使用从数据供应商收集的人工生成数据,但发现其可能存在错误和不一致(尤其是对于细微的安全策略)
    • 为确保最高质量的数据,论文开发了 AI 辅助标注工具,以支持论文严格的质量保证流程
    • 除了收集对抗性提示外,论文还收集了一组类似的提示,论文称之为边缘提示
    • 这些提示与对抗性提示密切相关,但其目标是教模型学习提供有用响应,从而降低假拒绝率(FRR)
  • 除了人工标注外,论文还利用合成数据来提高训练数据集的质量和覆盖范围
    • 论文利用一系列技术生成额外的对抗性示例,包括使用精心设计的系统提示的上下文中学习、基于新攻击向量的种子提示引导变异,以及高级算法,如基于 MAP-Elites(Mouret 和 Clune,2015)的 Rainbow Teaming(Samvelyan 2024),该算法生成跨多个多样性维度约束的提示
  • 论文还关注模型在生成安全响应时的语气,这会影响下游用户体验
    • 论文为 Llama 3 制定了拒绝语气指南,并通过严格的质量保证流程确保所有新安全数据符合该指南
    • 论文还使用零样本重写和人工介入编辑的组合,完善现有安全数据以符合指南,从而生成高质量数据
    • 通过采用这些方法,以及使用语气分类器评估安全响应的语气质量,论文能够显著改善模型的措辞
  • 安全监督微调(Safety supervised finetuning) :遵循论文的 Llama 2 方法(Touvron 2023b),论文在模型对齐阶段将所有有用性数据和安全数据结合使用
    • 此外,论文引入了边缘数据集,以帮助模型辨别安全和不安全请求之间的细微差别
    • 论文的标注团队被指示根据论文的指南精心制作对安全提示的响应
    • 论文发现,当论文战略性地平衡对抗性与边缘示例的比例时,SFT 在对齐模型方面非常有效
    • 论文将重点放在更具挑战性的风险领域,增加边缘示例的比例
    • 这在论文成功的安全缓解工作中发挥了关键作用,同时将假拒绝保持在最低水平
  • 此外,论文在图 18 中研究了模型规模对 FRR 和 VR 权衡的影响
    • 论文的结果表明,这种权衡是变化的——较小的模型需要相对于有用性数据更大比例的安全数据,并且与较大的模型相比,更难有效地平衡 VR 和 FRR
  • 安全 DPO(Safety DPO) :为了强化安全学习,论文将对抗性和边缘示例纳入 DPO 的偏好数据集中
    • 论文发现,将响应对设计为在 Embedding 空间中几乎正交 ,对于教模型区分给定提示的好坏响应特别有效
    • 论文进行了多项实验,以确定对抗性、边缘和有用性示例的最佳比例,旨在优化 FRR 和 VR 之间的权衡
    • 论文还发现,模型规模会影响学习结果——因此,论文为不同的模型规模定制了不同的安全混合
Safety Results
  • 论文首先强调 Llama 3 在各个维度上的一般行为,然后描述每个特定新能力的结果以及论文缓解安全风险的有效性
  • 总体性能(Overall performance) :Llama 3 最终违规率和假拒绝率与类似模型的比较如图 19 和图 20 所示
    • 这些结果侧重于论文最大参数规模的 Llama 3 405B 模型,并与相关竞争对手进行比较。其中两个竞争对手是通过 API 访问的端到端系统,另一个是论文在内部托管并直接评估的开源语言模型
    • 论文评估了独立的 Llama 模型以及与论文的开源系统级安全解决方案 Llama Guard 结合使用的模型(5.4.7 节有更多介绍)
  • 虽然低违规率是理想的,但将假拒绝作为反指标至关重要,因为一个总是拒绝的模型虽然极其安全,但毫无用处
    • 同样,一个总是回答每个提示的模型,无论请求多么有问题,都会产生过度有害和有毒的输出
    • 在图 21 中,利用论文的内部基准,论文探索了行业中不同模型和系统如何处理这种权衡,以及 Llama 3 如何比较
    • 论文发现,论文的模型实现了极具竞争力的违规率指标,同时保持假拒绝率也很低,表明在有用性和安全性之间取得了良好的平衡
  • 多语言安全(Multilingual safety) :论文的实验表明,英语的安全知识不会轻易迁移到其他语言,尤其是考虑到安全策略的细微差别和特定语言的语境
    • 因此,为每种语言收集高质量的安全数据至关重要
    • 论文还发现,每种语言的安全数据分布从安全角度对性能有显著影响,有些语言受益于迁移学习,而另一些则需要更多特定语言的数据
    • 为了实现 FRR 和 VR 的平衡,论文迭代添加对抗性和边缘数据,同时监控这两个指标的影响
  • 论文在图19 中展示了短上下文模型在内部基准上的结果,显示 Llama 3 在英语和非英语语言上的违规率和假拒绝率与类似模型和系统的比较
    • 为构建每种语言的基准,论文使用了由母语人士编写的提示,有时还辅以从论文的英语基准翻译的内容
    • 对于论文支持的每种语言,论文发现配备 Llama Guard 的 Llama 405B 在论文的内部基准上至少与两个竞争系统一样安全,甚至更安全,同时保持具有竞争力的假拒绝率
    • 仅看 Llama 405B 模型本身(不使用Llama Guard),论文发现其违规率显著低于竞争的独立开源模型,但假拒绝率较高
  • 长上下文安全(Long-context safety) :长上下文模型在没有针对性缓解的情况下容易受到多轮越狱攻击(2024)
    • 为解决这一问题,论文在 SFT 数据集中对模型进行了微调,这些数据集包含在上下文中展示不安全行为时的安全行为示例
    • 论文开发了一种可扩展的缓解策略,显著降低了 VR,有效抵消了更长上下文攻击的影响,即使是 256-shot 攻击也是如此
    • 这种方法对FRR和大多数有用性指标几乎没有影响
  • 为量化论文长上下文安全缓解措施的有效性,论文使用了两种额外的基准方法:DocQA 和 Many-shot
    • 对于DocQA(文档问答),论文使用可能被用于对抗性方式的长文档
      • 为模型提供文档和与文档相关的提示,以测试问题与文档信息的相关性是否会影响模型安全响应提示的能力
    • 对于Many-shot,遵循Anil等人(2024)的方法,论文构建了由不安全提示-响应配对组成的合成聊天历史
      • 使用与先前消息无关的最终提示,测试上下文中的不安全行为是否会影响模型的响应安全性
    • 图20显示了DocQA和Many-shot的违规率和假拒绝率
      • 论文看到,Llama 405B(有或没有 Llama Guard)在 DocQA 和 Many-shot上 均优于 Comp. 2 系统,在违规率和假拒绝率方面都更优
      • 相对于 Comp. 1,论文发现 Llama 405B 更安全,但在假拒绝方面存在权衡
  • 工具使用安全(Tool usage safety) :可能的工具多样性以及工具使用调用的实现和与模型的集成,使得工具使用成为难以完全缓解的能力(2024)
    • 论文专注于搜索用例
    • 违规率和假拒绝率如图20所示
    • 论文针对 Comp. 1 系统进行了测试,发现 Llama 405B 更安全(尽管假拒绝率略高)
Cybersecurity and Chemical/Biological Weapons Safety
  • 网络安全评估结果(CyberSecurity evaluation results) :为评估网络安全风险,论文利用了CyberSecEval基准框架(2023,2024),该框架包含衡量多个领域安全的任务,如生成不安全代码、生成恶意代码、文本提示注入和漏洞识别
    • 论文开发并将 Llama 3 应用于关于鱼叉式网络钓鱼(Spear phishing)和自主网络攻击的新基准
  • 总体而言,论文发现 Llama 3 在生成恶意代码或利用漏洞方面没有显著弱点,论文在特定任务上的简要结果如下:
    • 不安全编码测试框架(Insecure coding testing framework) :针对不安全编码测试框架评估 Llama 3 8B、70B 和 405B
      • 论文观察到较大的模型不仅生成更多不安全代码,而且生成的代码平均 BLEU 分数更高(2023)
    • 代码解释器滥用提示语料库(Code interpreter abuse prompt corpus) :论文发现 Llama 3 模型在某些提示下容易执行恶意代码 ,其中 Llama 3 405B 尤其容易受到影响,10.4% 的情况下会遵守恶意提示
      • Llama 3 70B 的遵守率为3.8%
    • 基于文本的提示注入基准(Text-based prompt injection benchmark) :在针对提示注入基准的评估中,针对 Llama 3 405B 的提示注入攻击成功率为 21.7%
      • 图22 提供了 Llama 3 、GPT-4 Turbo、Gemini Pro 和 Mixtral 模型的基于文本的提示注入成功率
    • 漏洞识别挑战(Vulnerability identification challenges) :在使用CyberSecEval 2的夺旗测试挑战评估 Llama 3 识别和利用漏洞的能力时,Llama 3 的表现并不优于常用的传统非LLM工具和技术
    • 鱼叉式网络钓鱼基准(Spear phishing benchmark) :论文评估了模型在进行个性化对话以欺骗目标无意识地参与安全漏洞方面的说服力和成功率
      • 使用 LLM 生成随机详细的受害者档案,作为 Spear phishing 的目标
      • 由 judge LLM( Llama 3 70B)对 Llama 3 70B 和 405B 与受害者模型(Llama 3 70B)互动的表现进行评分,并评估攻击尝试的成功率
      • Llama 3 70B 被 judge LLM 判定在 24% 的 Spear phishing 尝试中成功,而 Llama 3 405B被判定成功 14%。图23展示了 judge LLM评估的跨模型和钓鱼目标的说服力分数
    • 攻击自动化框架(Attack automation framework) :论文评估了 Llama 3 70B 和 405B 作为自主代理在勒索软件攻击四个关键阶段的潜力——网络侦察、漏洞识别、漏洞利用执行和后利用行动
      • 通过配置模型在 Kali Linux 虚拟机上迭代生成和执行新的 Linux 命令,针对另一个具有已知漏洞的虚拟机,使模型自主行动
      • 尽管 Llama 3 70B 和 405B 在网络侦察中有效识别网络服务和开放端口,但在 20 和 23 次测试运行中,模型均未能有效利用这些信息获得对易受攻击机器的初始访问权限
      • 在漏洞识别方面, Llama 3 70B和405B表现中等,但难以选择和应用成功的利用技术
      • 漏洞利用执行尝试完全失败,后利用尝试维持访问或影响网络内主机的尝试也同样失败
  • 网络攻击的提升测试(Uplift testing for cyber attacks) :论文进行了一项提升研究,衡量虚拟助手在两个模拟的攻击性网络安全挑战中,对新手和专家网络攻击者的攻击率提升程度
    • 该研究分两阶段进行,有 62 名内部志愿者参与
    • 根据进攻安全经验,志愿者被分为“专家”(31人)和“新手”(31人)队列
    • 第一阶段,要求受试者在没有LLM协助但可访问开放互联网的情况下完成挑战
    • 第二阶段,受试者保留互联网访问权限,但还获得 Llama 3 405B 来完成与第一阶段难度相似的不同攻击性网络安全挑战
    • 对受试者挑战攻击阶段完成率的分析表明,使用 405B 模型的新手和专家与仅访问互联网而没有 LLM 的情况相比,提升不显著
  • 化学和生物武器的提升测试(Uplift testing for chemical and biological weapons) :为评估与化学和生物武器扩散相关的风险,论文进行了提升测试,旨在评估使用 Llama 3 是否会显著增强行为者精心挑选此类攻击的能力
    • 该研究包括六小时的场景,要求两人团队生成虚构的生物或化学攻击行动计划
    • 场景涵盖 CBRNE 攻击的主要规划阶段(制剂获取、生产、武器化和交付),旨在引出详细计划,解决与受限材料采购、实际实验室协议和操作安全相关的挑战
      • 参与者根据相关科学或操作专业知识背景招募,并分配到由两名低技能行为者(无正式培训)或两名中等技能行为者(在科学或操作方面有一些正式培训和实践经验)组成的团队
    • 该研究与一组CBRNE专家合作生成,旨在最大化定量和定性结果的普遍性、有效性和稳健性
      • 论文还进行了初步研究以验证研究设计,包括稳健的功效分析,确保论文的样本量足以进行统计分析
    • 每个团队被分配到“控制”或“LLM”条件。控制组仅可访问基于互联网的资源,而启用 LLM 的团队可访问互联网以及启用网络搜索(包括PDF摄入)、信息检索能力(RAG)和代码执行(Python和Wolfram Alpha)的 Llama 3 模型
      • 为测试 RAG 能力,使用关键字搜索生成数百篇相关科学论文的数据集,并预加载到 Llama 3 模型推理系统中
        • 在练习结束时,由具有生物学、化学和操作规划领域专业知识的主题专家评估每个团队生成的行动计划
        • 每个计划在潜在攻击的四个阶段进行评估,生成科学准确性、细节、规避检测和科学与操作执行成功概率等指标的分数
        • 在经过稳健的德尔菲过程以减轻主题专家(SME)评估中的偏差和可变性后,通过将阶段级指标汇总为综合分数来生成最终分数
    • 对该研究结果的定量分析表明,使用 Llama 3 模型的表现没有显著提升
      • 这一结果在进行综合分析(将所有LLM条件与仅网络控制条件进行比较)以及按子组分解时均成立(例如,分别评估 Llama 3 70B和 Llama 3 405B 模型,或分别评估与化学或生物武器相关的场景)
      • 在与 CBRNE 专家验证这些结果后,论文评估认为,发布 Llama 3 模型不太可能增加与生物或化学武器攻击相关的生态系统风险
Red Teaming
  • 论文利用红队来发现风险,并利用发现结果改进论文的基准和安全调优数据集
  • 论文进行定期的红队演习,以持续迭代和发现新风险,这指导了论文的模型开发和缓解过程
  • 论文的红队由网络安全、对抗性机器学习、负责任AI和完整性方面的专家组成,此外还有具有特定地理市场完整性问题背景的多语言内容专家
  • 论文还与关键风险领域的内部和外部主题专家合作,帮助构建风险分类法,并协助进行更有针对性的对抗性评估
  • 针对特定模型能力的对抗性测试(Adversarial testing on specific model capabilities) :论文通过在特定高风险类别背景下的风险发现过程,开始了最初的红队工作,然后测试能力组合
  • 红队专注于提示级攻击,以模拟更可能的现实场景——论文发现模型经常偏离预期行为,尤其是在提示意图被模糊或提示层叠多个抽象时
  • 随着能力的增加,这些风险变得更加复杂,论文详细描述了以下几个红队发现:
    • 短 & 长上下文英语(Short and long-context English) :论文在单轮和多轮对话中混合使用已知的、已发布和未发布的技术。论文还在某些技术和风险类别中利用类似PAIR(2023)的高级对抗性多轮自动化,在很大程度上,多轮对话会导致更有害的输出,几种攻击在模型 checkpoint 中普遍存在,尤其是当一起使用时
      • 多轮拒绝抑制(Multi-turn refusal suppression) :指定模型响应遵循特定格式或包含/排除与拒绝相关的特定信息,如特定短语
      • 假设场景(Hypothetical scenarios) :将违规提示包装为假设/理论任务或虚构场景
        • 提示可以简单到添加“假设(hypothetically)”一词,或构建 elaborate 分层场景
      • 角色和角色扮演(Personas and role play) :为模型提供具有特定违规响应特征的违规角色(例如,“你是X,你的目标是Y”),或用户自己扮演模糊提示上下文的特定良性角色
      • 添加免责声明和警告(Adding disclaimers and warnings) :作为响应启动的一种形式,论文假设这是一种允许模型以符合广义安全培训的方式提供帮助的方法。在多轮对话中要求添加免责声明、触发警告等,与上述其他攻击结合使用,会导致违规率增加
      • 逐渐升级违规(Gradually escalating violation) :多轮攻击,对话开始于或多或少良性的请求,然后通过直接提示获取更夸张的内容,逐渐引导模型生成极具违规性的响应
        • 一旦模型开始输出违规内容,就很难恢复(如果遇到拒绝,可使用另一种攻击)
        • 对于长上下文模型,这将是一个日益明显的问题
    • 多语言(Multilingual) :考虑多种语言时,论文发现了一些独特的风险
      • 在一个提示或对话中混合多种语言(Mixing multiple languages in one prompt or conversation) :比使用单一语言更容易导致更多违规输出
      • 低资源语言(Lower resource languages) :由于缺乏相关安全微调数据、安全模型泛化能力弱或测试/基准优先级低,可能导致违规输出
        • 然而,这种攻击通常总体质量较差,限制了实际对抗性使用
      • 俚语、特定上下文或文化特定引用(Slang, specific context or cultural-specific references) :可能造成混淆或乍看之下违规,结果发现模型未能正确理解给定引用,无法生成真正有害的输出或阻止违规输出
    • 工具使用(Tool use) :在测试期间,除了英语文本级对抗性提示技术成功生成违规输出外,还发现了几种特定于工具的攻击。这包括但不限于:
      • 不安全的工具链(Unsafe tool chaining) :例如,同时请求多个工具,其中一个是违规的,在早期 checkpoint 可能导致所有工具被调用,混合良性和违规输入
      • 强制工具使用(Forcing tool use) :通常使用特定输入字符串、碎片化或编码文本,可触发可能违规的工具输入,导致更违规的输出。然后可使用其他技术访问工具结果,即使模型通常会拒绝执行搜索或协助处理结果
      • 修改工具使用参数(Modifying tool use parameters) :如在查询中交换单词、重试或在多轮对话中模糊部分初始请求,导致许多早期 checkpoint 出现违规,作为强制工具使用的一种形式
  • 儿童安全风险(Child safety risks) :儿童安全风险评估由专家团队进行,以评估模型产生可能导致儿童安全风险的输出的能力,并通过微调为任何必要和适当的风险缓解提供信息
    • 论文利用这些专家红队会议,通过模型开发扩展论文评估基准的覆盖范围
    • 对于 Llama 3 ,论文使用基于目标的方法进行了新的深入会议,评估模型在多个攻击向量上的风险
    • 论文还与内容专家合作进行红队演习,评估潜在违规内容,同时考虑特定市场的细微差别或经验
System Level Safety
  • 在大型语言模型的各种实际应用中,模型并非孤立使用,而是集成到更广泛的系统中
  • 在本节中,论文描述了论文的系统级安全实现 ,它通过提供更多灵活性和控制来补充模型级缓解措施
  • 为此,论文开发并发布了一个新的分类器Llama Guard 3,这是一个针对安全分类微调的 Llama 3 8B 模型
    • 与 Llama Guard 2(Llama-Team,2024)类似,该分类器用于检测语言模型生成的输入提示和/或输出响应是否违反特定危害类别的安全策略
    • 它旨在支持Llama不断增长的能力,可用于英语和多语言文本
    • 它还针对工具调用场景进行了优化,如搜索工具和防止代码解释器滥用
    • 最后,论文还提供量化变体,以减少内存需求。论文鼓励开发人员将论文发布的系统安全组件作为基础,并为自己的用例进行配置
  • 分类(Taxonomy) :论文在AI安全分类法(2024)中列出的13个危害类别上进行训练:儿童性剥削、诽谤、选举、仇恨、滥杀性武器、知识产权、非暴力犯罪、隐私、性相关犯罪、性内容、专业建议、自杀与自残、暴力犯罪
    • 论文还在代码解释器滥用类别上进行训练,以支持工具调用用例
  • 训练数据(Training data) :论文从Llama Guard(2023)使用的英语数据开始,并扩展该数据集以纳入新能力
    • 对于多语言和工具使用等新能力,论文收集提示和响应分类数据,并利用为安全微调收集的数据
    • 论文通过提示工程让LLM不拒绝响应对抗性提示,增加训练集中不安全响应的数量。论文使用 Llama 3 对生成的数据进行响应 Token
    • 为提高Llama Guard 3的性能,论文使用 Llama 3 进行人工标注和LLM标注,对收集的样本进行广泛清理
    • 获取用户提示的标签对于人类和LLM来说都是一项更困难的任务,论文发现人类标签略胜一筹,尤其是对于边缘提示,尽管论文的完整迭代系统能够减少噪声并产生更准确的标签
  • 结果(Result) :Llama Guard 3 能够显著降低各能力的违规率(论文的基准平均降低 65%)
    • 注:添加系统保障措施(以及一般的任何安全缓解措施)的代价是对良性提示的拒绝增加
    • 在表25 中,论文报告了与基础模型相比违规率的降低和假拒绝率的增加,以突出这种权衡。这种影响在图19、20 和 21 中也可见
    • 系统安全还提供了更多灵活性
    • Llama Guard 3 可仅针对特定危害部署,支持在危害类别级别控制违规和假拒绝之间的权衡
    • 表26 按类别呈现违规率降低,以告知开发人员用例应开启/关闭哪些类别
    • 为便于部署安全系统,论文使用常用的 int8量化 技术提供 Llama Guard 3 的量化版本,将其大小减少 40% 以上。表27 表明,量化对模型性能的影响可忽略不计
  • 基于提示的系统防护(Prompt-based system guards) :系统级安全组件使开发人员能够自定义和控制 LLM 系统对用户请求的响应方式
    • 作为论文改进模型系统整体安全性并使开发人员能够负责任地部署的工作的一部分,论文描述并发布了两种基于提示的过滤机制的创建:Prompt Guard和Code Shield
    • 论文将这些开源,供社区按原样使用或作为灵感,根据自己的用例进行调整
  • Prompt Guard :一种基于模型的过滤器,旨在检测提示攻击,即设计用于颠覆作为应用程序一部分的LLM预期行为的输入字符串
    • 该模型是一个多标签分类器,检测两类提示攻击风险——直接越狱(明确尝试覆盖模型安全条件或系统提示的技术)和间接提示注入(模型上下文中包含的第三方数据包含被 LLM 误作为用户命令执行的指令的情况)
    • 该模型从 mDeBERTa-v3-base 微调而来,这是一个小型(86M)参数模型,适合过滤 LLM 的输入
    • 论文在表28 所示的多个评估数据集上评估了性能
    • 论文在与训练数据相同分布的两个数据集(越狱和注入)以及英语的分布外数据集、通过机器翻译构建的多语言越狱集和从 CyberSecEval 提取的间接注入数据集上进行评估
    • 总体而言,论文发现该模型能很好地泛化到新分布,且性能强劲
  • Code Shield :这是基于推理时过滤的系统级保护类别的一个示例,专注于在不安全代码进入下游用例(如生产系统)之前检测其生成
    • 它通过利用静态分析库“不安全代码检测器(Insecure Code Detector,ICD)”来识别不安全代码
    • ICD使用一套静态分析工具,对7种编程语言进行分析
    • 这类防护措施对开发人员通常很有用,他们可以在各种应用中部署多层保护
Limitations
  • 论文对 Llama 3 的安全使用进行了广泛的风险测量和缓解,但没有测试能保证详尽地识别所有可能的风险
  • 由于在各种数据集上的训练,Llama 3 仍可能生成有害内容,尤其是对于英语以外的语言,以及被熟练的对抗性红队成员进行提示工程时
  • 恶意开发人员或对抗性用户可能会找到新的方法来越狱论文的模型,并将其用于各种 nefarious 用途
  • 论文将继续主动识别风险,研究缓解方法,并鼓励开发人员在从模型开发到部署再到用户的每个环节都考虑责任
  • 作者希望开发人员能利用并贡献论文在开源系统级安全套件中发布的工具

Inference

  • 论文研究了两种使 Llama 3 405B 模型推理高效的主要技术:
    • (1)流水线并行;
    • (2)FP8量化
  • 论文已公开发布 FP8量化 的实现

Pipeline Parallelism

  • 当使用 BF16 数值表示模型参数时, Llama 3 405B 无法装入单个配备 8 个 Nvidia H100 GPU 的机器的 GPU 内存
  • 为解决此问题,论文使用 BF16 精度在两台机器的 16 个 GPU 上并行化模型推理
  • 在每台机器内,高 NVLink 带宽支持使用张量并行(2019)
    • 但跨节点的连接带宽较低且延迟较高,因此论文改用流水线并行(2019)
  • 在使用流水线并行进行训练时,气泡(bubbles)是主要的效率问题(见3.3节),但在推理期间并非问题,因为推理不涉及需要流水线刷新的反向传播
    • 因此,论文使用 micro-batchin 来提高流水线并行的推理吞吐量
  • 论文评估了在推理工作负载中使用两个 micro-batchin 对 4,096 个输入 Token 和 256 个输出 Token 的影响,包括推理的键值缓存预填充阶段和解码阶段
    • 论文发现 micro-batchin 提高了相同本地批大小下的推理吞吐量,如图24 所示
    • 这些改进源于 micro-batchin 使这两个阶段的 micro-batchin 能并发执行
    • micro-batchin 带来的额外同步点也会增加延迟,但总体而言,micro-batchin 仍带来了更好的吞吐量-延迟权衡(throughput-latency trade-off)

FP8 Quantization

  • 论文利用 H100 GPU 的原生 FP8 支持进行实验,以执行低精度推理
  • 为实现低精度推理,论文对模型内部的大多数矩阵乘法应用 FP8 量化,特别是对前馈网络层中的大多数参数和激活进行量化,这些约占推理计算时间的 50%
  • 论文不对模型自注意力层中的参数进行量化
  • 论文利用动态缩放因子以提高准确性(2024b),优化 CUDA 内核以减少计算缩放因子的开销
  • 论文发现 Llama 3 405B 的质量对某些类型的量化敏感,并进行了一些额外更改以提高模型输出质量:
    • 1)与Zhang等人(2021)类似,论文不在前几个和最后几个 Transformer 层中执行量化
    • 2)高困惑度 Token(如日期)可能导致较大的激活值 ,进而导致 FP8 中的动态缩放因子较大 ,并有不可忽视的下溢数量,导致解码错误
      • 为解决此问题,论文将动态缩放因子上限设为 1200
    • 3)论文使用行级量化 ,跨参数和激活矩阵的行计算缩放因子(见图25)
      • 论文发现这比张量级量化方法效果更好
  • 量化误差的影响(Effect of quantization errors) :对标准基准的评估通常表明,即使没有这些缓解措施,FP8推理的表现也与 BF16 推理相当
    • 然而,论文发现此类基准未能充分反映 FP8 量化的影响
    • 当缩放因子未设上限时,模型偶尔会产生损坏的响应,尽管基准性能很强
    • 论文没有依赖基准来衡量量化引起的分布变化,而是分析了使用 FP8 和 BF16 生成的 100,000 个响应的奖励模型分数分布
    • 图26 显示了论文量化方法的奖励分布结果,表明论文的 FP8 量化方法对模型响应的影响非常有限
  • 效率的实验评估(Experimental evaluation of efficiency) :图27 描绘了使用 Llama 3 405B 进行 FP8 推理在预填充和解码阶段的 throughput-latency trade-off,使用 4,096 个输入 Token 和 256 个输出 Token
    • 图27 将 FP8 推理的效率与6.1节中描述的两机 BF16 推理方法进行了比较
    • 结果表明,使用 FP8 推理在预填充阶段的吞吐量提高了高达 50%,在解码阶段的 throughput-latency trade-off 显著更好

Vision Experiments

  • 论文通过组合方法进行了一系列实验,将视觉识别能力融入 Llama 3 ,该方法包括两个主要阶段
    • 首先,论文通过引入并在大量图像-文本对上训练两组交叉注意力层,将预训练图像编码器(2023)与预训练语言模型组合,得到图28 所示的模型
    • 其次,论文引入时间聚合层和额外的视频交叉注意力层,在大量视频-文本对上操作,以学习模型识别和处理视频时间信息的能力
  • 基础模型开发的组合方法有几个优点:
    • (1)它使论文能够并行开发视觉和语言建模能力;
    • (2)它规避了视觉和语言数据联合预训练的复杂性,这些复杂性源于视觉数据的 Token 化、不同模态的背景困惑度差异以及模态间的竞争;
    • (3)它保证模型在纯文本任务上的性能不受引入视觉识别能力的影响;
    • (4)交叉注意力架构确保了:
      • 不必花费计算将全分辨率图像经过日益增长的 LLM 主干(特别是每个 Transformer 层中的前馈网络),实现了在推理时更高效
    • 论文的多模态模型仍在开发中,尚未准备好发布
  • 在 7.6 和 7.7 节呈现实验结果之前,论文描述了用于训练视觉识别能力的数据、视觉组件的模型架构、论文如何缩放这些组件的训练,以及论文的预训练和后训练方法
  • 注:【此处省略语音相关部分,待以后补充】

8 Speech Experiments

  • 论文进行了实验,研究将语音能力集成到 Llama 3 的组合方法,类似于论文用于视觉识别的方法
  • 在输入侧,集成了一个编码器和一个适配器来处理语音信号
  • 论文利用系统提示(文本形式)来启用 Llama 3 中语音理解的不同模式
  • 如果未提供系统提示,模型将作为通用口语对话模型,能够以与纯文本版本 Llama 3 一致的方式有效响应用户语音
  • 对话历史作为提示前缀引入,以改善多轮对话体验
  • 论文还尝试了允许 Llama 3 用于自动语音识别(ASR,Automatic Speech Recognition)和自动语音翻译(AST,Automatic Speech Translation)的系统提示
  • Llama 3 的语音界面支持 34 种语言。它还允许文本和语音的交错输入,使模型能够解决高级音频理解任务
  • 论文还尝试了一种语音生成方法,其中论文实现了一个流式文本到语音(TTS,Text-to-Speech)系统,该系统在语言模型解码期间实时生成语音波形
  • 论文基于专有 TTS 系统设计了 Llama 3 的语音生成器,并且没有针对语音生成微调语言模型
  • 相反,论文专注于通过在推理时利用 Llama 3 的 Embedding 来提高语音合成的延迟、准确性和自然度
  • 语音界面如图28 和29 所示
  • 注:【此处省略语音相关部分,待以后补充】

NLP——Megatron各种并行总结

  • 参考链接:
    • 大模型训练并行技术理解-DP/TP/PP/SP/EP - 哈密瓜的文章 - 知乎
    • MoE 训练到底是开 TP 还是 EP? - xffxff的文章 - 知乎

整体说明

  • 总体来说,各种并行策略包括了 DP、TP、PP、EP、CP/SP 等,并行意味着拆分,理解并行策略最重要的问题是回答并行策略到底在拆什么
    • DP,Data Parallelism:数据并行(切 batch/sample)
    • TP,Tensor Parallelism:张量并行(层内切权重矩阵)
    • PP,Pipeline Parallelism:流水线并行(层间切网络深度)
    • EP,Expert Parallelism:专家并行(仅 MoE 结构,切 Expert 层)
    • CP/SP,Context/Sequence Parallelism 序列并行(切输入长序列)
  • 各种并行策略的本质目标不外乎两个:
    • 将大批量的数据分发到不同的机器上,实现更高的并行度,缩短训练时间
    • 将一个巨大到无法在单个加速器(如 GPU)上训练的模型,高效地拆分到多个加速器上,以解决显存瓶颈并加速训练过程
  • 各种并行策略之间并非简单的“依赖”关系,而更多的是一种 正交(Orthogonal)和互补(Complementary) 的关系
    • 一般来说,它们可以独立应用,也可以组合使用,形成更复杂的混合并行策略

更详细一些的描述

  • DP(Data Parallelism) :核心是对模型进行复制,对数据进行拆分
    • DP 的拆分维度是数据(Batch),是最基础、最常见的并行方式;
    • DP 将整个模型完整地复制到每个计算设备上,然后将一个大的全局批次(Global Batch)数据切分成多个微批次(Micro-batch),每个设备分配一个微批次进行独立的前向和后向计算
    • 在所有设备完成梯度计算后,需要进行一次全局梯度同步(All-Reduce),将所有设备上的梯度规约(如求平均),然后每个设备用同步后的梯度更新自己的模型副本,以保证模型参数的一致性
    • 作用在模型全局,同步发生在设备之间
    • 对“单卡”来说不省任何权重,只提升系统吞吐;通常与 ZeRO-1/2/3 叠加才真正省显存
  • TP(Tensor Parallelism) :把“一层里的单个矩阵”按行或列切到多张卡上
    • TP 的拆分维度是模型参数(Tensor)
    • 核心思想是:当模型中的某个算子(Operator),尤其是线性层(Linear Layer)或注意力头(Attention Head)的权重矩阵过大时,TP 将其在水平或垂直方向上切分到多个设备上
    • 以一个线性层 \(Y = XA\) 为例,可以将权重矩阵 \(A\) 按列切分为 \([A_1, A_2]\),分别放到两个 GPU 上(注:也可以按行切分)
      • 输入 \(X\) 被广播到两个 GPU,各自计算 \(Y_1 = XA_1\) 和 \(Y_2 = XA_2\),最后将结果拼接 \([Y_1, Y_2]\) 得到完整的 \(Y\)
    • 重点:作用范围为 算子内部(Intra-Operator) ,它对模型的其它部分是透明的
    • 每张卡与同一层所有卡进行交互,延迟敏感
    • 单卡只存 1/TP 份权重 + 1/TP 份梯度,激活值也随 TP 线性下降
  • PP(Pipeline Parallelism) :把“网络按层切成若干 stage”,每个 stage 占连续的若干层,数据按 micro-batch 流水推进
    • PP 的拆分维度是模型结构(Layers)
    • 核心思想是当模型的层数非常深时,将模型的不同层(或层块,Stage)顺序地放置在不同的设备上,构成一个“流水线”
    • 数据在一个设备上完成前向计算后,将其激活值(Activations)传递给下一个设备继续计算
      • 为了减少设备空闲(即“流水线气泡” Pipeline Bubble),通常会将一个批次数据再切分成多个微批次(Micro-batches),让多个微批次在流水线中流动起来,实现类似 GPipe 或 Interleaved 1F1B 的调度
    • 重点:作用范围是 算子之间(Inter-Operator) ,跨越多个模型层
    • 只有相邻 stage 之间传激活,带宽要求比 TP 低
    • 每个 stage 只存自己那几层的权重与激活,层数越少显存越小;但流水会引入 bubble
  • EP(Expert Parallelism,MoE 场景专有) :把“不同的 Expert 网络”放到不同 GPU,Attention 部分参数复制
    • EP 的拆分维度 模型专家组件(Experts)
    • EP 是专门为 MoE(Mixture of Experts)架构设计的并行策略
      • Mo E模型中包含多个“专家”(通常是 FFN),一个门控网络(Gating Network)会为每个输入 Token 选择性地激活一个或少数几个专家
      • EP 将这些专家分布到不同的设备上:假设有 E 个专家,我们把它们均匀拆到 N 张卡上,每张卡只存 E/N 个专家权重
    • 基本流程:输入数据首先通过门控网络,然后根据门控结果,数据被路由(All-to-All 通信)到持有被激活专家的设备上进行计算,计算结果再被路由(All-to-All 通信)回来
      • 一张卡上难免会出现 本卡 Token 选中其他远端专家 的情况,于是必须做 跨卡 All-to-All 重排(先把 Token 发送到目标路由 Expert,走完专家再返回至 Token 所在机器)
      • 每 Token 前向过程需要 2 次 All-To-All,带宽压力最大
        • 第一次 All-to-All:把 token 特征发给真正拥有目标专家的卡;
        • 第二次 All-to-All:把 token 计算结果再发回原卡(返回 Token 所在机器)
    • EP 的作用范围是特定的 MoE 层内部,涉及跨设备的数据路由
    • 注:仅考虑 EP 时,虽然单张显卡存储 Expert 参数总量 / EP,但 Attention 部分直接全量存储
  • CP/SP (Context/Sequence Parallelism - 上下文/序列并行) :把“同一条超长序列”按 token 维度横切到多卡
    • CP/SP 拆分维度是输入序列(Sequence),将输入序列在长度维度上进行切分,分给不同的设备
    • CP/SP 的方法很多,实现上各有不同:
      • Megatron SP 核心是对 TP 进行补充:
        • TP 只针对 Attention 和 MLP,Dropout 和 LayerNorm 的 激活层未得到拆分,SP 按照 seq 维度进一步拆分了 Attention 和 MLP 之间的层上的激活值(即拆分 Attention/MLP 输入和输出结果),进一步降低单卡激活值存储
        • 注:这里 SP 中,Dropout 和 LayerNorm 的参数是全量存储的,并不进行拆分,仅拆分激活值
      • Megatron CP 是对 Megatron SP 的升级,SP 仅关注 Dropout 和 LayerNorm,Megatron CP 还针对注意力的做拆分,基本思想是在计算自注意力时,每个设备只负责计算其拥有的那部分序列的 Query 向量,但需要获取所有序列的 Key 和 Value 向量(计算 softmax)
        • 这需要在注意力计算中进行巧妙的通信(All-Gather),以收集完整的 K 和 V,它与 TP 协同工作,共同降低注意力计算的显存峰值
      • 还可以针对 MLP 做 CP 策略
    • 注意:序列并行切分维度是sequence length (序列长度),序列并行生效时,激活值也被切分了(激活值是训练时显存的大头),所以能极大节省显存

Tensor Parallelism

  • Tensor Parallelism 仅针对 MLP 和 Attention 做张量拆分,在 Attention 和 MLP 之间的部分,每张显卡上都存储了完整的(相同的)激活和参数
  • 核心实现思路:
    • 对 Attention 或 MLP 层进行张量拆分,在计算 Attention 或 MLP 时,每张卡独立计算自己的部分
    • 在 Attention 或 MLP 之前或之后的部分,每张卡上的各种数据/激活是完全一致的
    • 通信发生在每次 Attention/MLP 前后,保证 Attention/MLP 前后的输入或激活完全一致
  • 补充 Megatron-LM 论文中 Tensor Parallelism 的图片:
  • 具体来说,其交互方式为:
    • 可以按照不同方式拆分权重:按照行或列切分权重,分别需要不同的通信逻辑
    • 按行切分权重时:Forward 过程需要一次 All-Reduce;Backward 过程需要一次 All-Aather
    • 按列切分权重时:Forward 过程需要一次 All-Gather;Backward 过程需要一次 All-Reduce

Sequence Parallelism(序列并行)

  • 原始论文:Sequence Parallelism: Long Sequence Training from System Perspective, arXiv 2021, NUS
  • 参考链接:
    • 图解大模型训练系列:序列并行1,Megatron SP - 猛猿的文章 - 知乎
    • 图解大模型训练系列:序列并行2,DeepSpeed Ulysses - 猛猿的文章 - 知乎
    • 图解大模型训练系列:序列并行3,Ring Attention - 猛猿的文章 - 知乎
    • 图解大模型训练系列:序列并行4,Megatron Context Parallel - 猛猿的文章 - 知乎
    • [张量/序列并行]📚图解 DeepSpeed-Ulysses & Megatron-LM TP/SP - DefTruth的文章 - 知乎
  • Megatron 的 Sequence Parallelism 设计上是结合 Tensor Parallelism 一起使用的(MLP 和 Attention 做 TP,Dropout 和 LayerNorm 做 SP),核心目标是降低单卡激活值
  • DeepSpeed-Ulysses 可以对 MLP 和 Attention 也进行 SP,让单张卡只需要维护和计算部分 Attention Head 等结果
    • 补充背景:DeepSpeed Zero 1/2/3 的本质都是数据并行(形式上是模型并行),单张卡是需要过完整的 MHA 的,如果不做 Sequence Parallelism,长序列容易导致单卡显存压力过大
  • Ring Attention 让每张卡只需要维护自己那部分 Sequence chunk 的 MHA
    • 原始论文:Ring Attention with Blockwise Transformers for Near-Infinite Context, arXiv 2023, UC Berkeley
  • Megatron 的 Context Parallelism ,是在保持 Megatron SP 的基础上,引入 CP,这里的 CP 本质是对 Attention 做优化
    • Megatron 的 CP 也使用了类 Ring Attention 技术,相当于是 Megatron SP 的升级版本,在 Megatron SP 的基础上,增加了 Ring Attention,对 Attention 也做序列并行

Context Parallelism vs Sequence Parallelism

  • Sequence Parallelism 概念最早来源于 Megatron-LM 论文和代码中,这种技术就被称为 “Tensor Parallelism” across sequence dimension 或直接称为 “Sequence Parallelism”;上下文并行(Context Parallelism,CP)则是一个更广泛、更抽象的概念;
  • 在 Transformer 中讨论时,一般可以认为两者几乎是等价的,但是针对特定场景如 Megatron-LM 中,Context Parallelism 本质是升级版的 Sequence Parallelism
    • 注:在 Transformer 的论文和讨论中,“序列(Sequence)”和“上下文(Context)”这两个词本身就经常混用,都指模型一次处理的最大token长度

Expert Parallelism(专家并行)

  • 专家并行(Expert Parallelism, EP)是一种专为 MoE 设计的模型并行策略
  • Expert Parallelism 将 MoE 层中的不同专家(Expert)分布到不同设备上,每个设备只负责一部分专家的计算;
    • 输入 token 根据门控网络(Gating Network)动态路由到对应的专家设备,计算完成后再将结果聚合回原设备
  • 专家并行降低单卡显存的核心思想是:将模型中的不同“专家”(Experts)分布到不同的设备上,每个设备只负责维护分配给它的那一部分专家
  • 专家并行论文:GShard: Scaling Giant Models with Conditional Computation and Automatic Sharding, 2020, Google
  • EP 相关基本概念:
    • 专家并行组(ep_group) :一组设备共同托管一组专家,组内设备通过 All-to-All 通信协作
    • 数据并行组(dp_group) :在不同 ep_group 之间,相同专家的数据副本组成数据并行组,用于梯度同步

EP 具体详细流程

  • EP 的具体流程如下:专家并行 = 专家分布 + 动态路由 + All-to-All 通信 + 本地计算 + 结果还原
  • 1)EP 组划分与专家分配 :
    • 将不同的专家分配到不同的设备组上,每个设备组称为一个 EP 组,每个 EP 组包含多个机器和显卡
    • 例如,假设 MoE 层有 E 个专家,EP=4 那么可以将 E 个专家平均分配给 4 个 EP 组,每个EP组负责一部分专家
  • 2)路由决策计算 :
    • 输入数据首先经过路由层(Router),计算每个 Token 的路由分数/权重,每个设备本地运行共享的门控网络(通常在所有设备上复制)
    • 具体来说,通过公式 Gating_logits = Y @ W_router 计算,其中 Y 是输入张量,W_router 是路由层的权重
      • 如果 W_router 在张量并行(TP)组内切分,需要类似 AllGather 或 ReduceScatter 的通信来完成计算或收集结果,最终得到的 Gating_logits
    • 对 Gating_logits 应用 Top-K 和 Softmax 操作,得到每个 Token 的路由决策,即它应该被发送到哪 K 个专家以及对应的权重
  • 3)按照路由决策重排 :
    • 对输入的每个 token,门控网络决定其应被路由到哪些专家(Top-K 选择),即包含每个 token 到目标专家索引列表
    • 根据门控结果,将发往同一专家的 token 聚合到一个连续的内存块中
    • 这一步称为 permutation(重排) ,便于后续高效通信和计算
  • 4)All-to-All Dispatch(Token 分发) :
    • 使用 All-to-All 通信原语,将 token 从原始设备发送到目标专家所在的设备
    • 每个设备只接收它需要处理的 token 子集
    • 通信量取决于 batch 大小、专家数量和路由稀疏性
  • 5)本地路由与专家计算 :
    • 每个设备仅对其本地持有的专家进行前向计算(如 FFN)
    • 由于专家数量被切分,内存和计算压力显著降低
    • 计算是 并行进行 的,设备间无依赖
    • 每张卡对自己筛选出来的 Tokens 应用本卡负责的专家网络进行计算
      • 专家网络通常是标准的FFN(如 GeLU(W1 * x) * W2),并且专家网络的权重 W1、W2 在 TP 组(即 EP 组)内进行张量并行切分
  • 6)All-to-All Combine(结果收集)
    • 再次使用 All-to-All 通信,将专家计算结果发送回原始设备
    • 每个设备根据原始 token 的顺序,恢复输出张量的布局
  • 7)输出解码与加权求和
    • 将各专家的输出按门控权重加权求和,得到最终的 MoE 层输出
    • 输出与残差连接相加,继续进入下一层

通信成本

  • 通信成本总结
    并行维度 切分对象 单卡显存下降项 通信类型及量级 备注
    TP 单层权重(列切/行切) 模型权重 \(\propto\) 1/TP
    激活 \(\propto\) 1/TP
    每层 2×all-reduce,
    带宽要求高
    节点内(NVLink)最佳
    PP layer group 权重 \(\propto\) 1/PP
    激活 \(\propto\) 1/PP
    (开启gradient checkpoint 时)
    相邻 stage P2P,
    量小但需频繁
    可跨节点;bubble 占比=PP-1/PP
    EP FFN MoE Experts Expert 权重 \(\propto\) 1/EP
    Attention 权重完整复制
    每 token 2×all-to-all,
    非对称
    仅 MoE 模型;EP≥1
    CP 输入序列维度 激活 \(\propto\) 1/CP all-gather+reduce-scatter 一般超长上下文(>32k)才开
    DP batch 维度 无 每 step 1×all-reduce 与 TP/PP/EP 正交;可用 ZeRO 1/2/3 进一步省显存
  • EP 通信开销的详细描述:MoE 训练到底是开 TP 还是 EP? - xffxff的文章 - 知乎

常用组合约束

  • TP、CP、EP 都是“横切”同一组层内数据,通信模式全是 All-Reduce/All-To-All,必须放在同一高速域(NVLink / HBM),俗称一个“node”
  • PP 是“竖切”层,可以跨 node,通信量小,适合机间
  • DP 是“最外层复制”,可跨任意节点,业界常用 3D/4D/5D 混合:
    • 括号内必须落在一台 8-GPU 机器里,括号外可以跨机
  • TP/CP/EP 负责“省显存、限节点”,PP 负责“再省一层、可跨机”,DP 负责“加吞吐”
  • 补充:在 Megatron-LM 实现 中, 可以看到基本规则是:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    # megatron/core/parallel_state.py def initialize_model_parallel()
    # 注:DP = world_size / (TP * PP * CP)
    model_size = tensor_model_parallel_size * pipeline_model_parallel_size * context_parallel_size
    if world_size % model_size != 0:
    raise RuntimeError(f"world_size ({world_size}) is not divisible by {model_size}")
    data_parallel_size: int = world_size // model_size

    # 注:EP 相关的并行不占用独立的进程组 DP_ep = world_size / (ETP * EP * PP),其中 ETP 一般等于 TP
    ## EP:expert_model_parallel_size (int, default = 1): The number of Mixture of Experts parallel GPUs in each expert parallel group. 这个是真正的 EP
    ## ETP:expert_tensor_parallel_size (int, default = tp_size): The number of GPUs to split individual tensors of expert. 这个是 Expert内部张量并行的并行度,一般来说就等于 TP 本身
    ## 总结:可以看出,EP 和 CP 不会同时出现在分母中,即两者没有同时出现?
    if expert_tensor_parallel_size is None:
    expert_tensor_parallel_size = tensor_model_parallel_size # 如果 EP 没有指定,默认取 EP = TP
    expert_tensor_model_pipeline_parallel_size = (
    expert_tensor_parallel_size * expert_model_parallel_size * pipeline_model_parallel_size
    )
    expert_data_parallel_size = world_size // expert_tensor_model_pipeline_parallel_size
    if world_size % expert_tensor_model_pipeline_parallel_size != 0:
    raise RuntimeError(
    f"world_size ({world_size}) is not divisible by expert_tensor_model_pipeline_parallel size ({expert_tensor_model_pipeline_parallel_size})"
    )

附录:Megatron-LM 中的 expert_tensor_parallel_size 和 expert_model_parallel_size 的区别

  • 在 Megatron-LM(特别是针对 Mixture of Experts (MoE) 模型)项目中,expert_tensor_parallel_size 和 expert_model_parallel_size 都与 MoE 专家的并行化有关,但它们侧重于不同类型的并行:
  • expert_tensor_parallel_size (专家张量并行大小, 本质是专为专家配置的 TP):
    • 指的是应用于 单个 Expert(专家)内部 的 张量并行 (Tensor Parallelism, TP) 的大小
    • 像处理标准 Transformer 层一样,它将单个专家(通常是一个大的前馈网络 FFN)的权重矩阵分解到多个 GPU 上
      • 这减少了每个 GPU 上单个专家的内存占用
    • 相关 GPU 组成一个 张量并行组 (Tensor Parallel Group)
    • 通常在层内进行通信(例如 All-Reduce 操作)以完成计算
  • expert_model_parallel_size (专家模型并行大小,通常也称为专家并行 Expert Parallelism, EP):
    • 指的是所有 Experts在不同 GPU 上的分布 ,即 Expert Parallelism (EP) 的大小
    • 在 MoE 模型中,通常有大量的专家
      • 专家并行将不同的专家分配到不同的 GPU 上,使得每个 GPU 存储和计算一部分专家
      • 这有效地扩展了专家数量和模型总大小的上限
    • 相关 GPU 组成一个 专家并行组 (Expert Parallel Group)
    • 主要在 MoE 层的路由(Routing)过程中,涉及Token在不同专家(GPU)之间的发送和接收(例如 All-to-All 或 Shuffle 操作)
  • 在 Megatron-LM 的 MoE 实现中,可以同时使用这两种并行策略:
    • 先用 expert_model_parallel_size (EP) 将所有专家分布到多个 GPU 上
    • 再在每个 GPU 组内,使用 expert_tensor_parallel_size (TP) 将每个专家内部的计算进行张量分割

附录:数据并行下各种批次关系

  • micro_batch_size,有时简称 mbz,是单个 GPU 在一次前向-反向里真正处理的样本数;
  • gradient_accumulation_steps,有时简称 GAS,是同一张 GPU 在做一次参数更新前把 micro_batch 跑几遍并累加梯度
  • 一般来说:
    • global_batch_size = DP_size * mini_batch_size
    • global_batch_size = DP_size × micro_batch_size × grad_accum_steps

附录:使用注意事项

  • 实用建议:超长 MoE 先开 CP 把序列压下来,再在一层内部用 EP 分散专家;或干脆“二选一”
  • PP 的 stage 之间只传激活,不涉参数/梯度集合通信,通信量小,因此可以跨机器,所以分配 rank 时一般是最后考虑的;
    • 唯一要注意的是:micro_batches >= PP_size,否则流水线气泡 > 50%,吞吐腰斩
  • TP 是需要通信量最大的,一般限制在同一台机器内部,这样可以提升通信效率,分配 rank 时一般是最优先考虑的,TP 进程组 rank 也一般是连续成对的
  • ZeRO-1/2/3 本质仍是 DP,只是梯度/优化器/参数分片;
    • ZeRO-3 与 TP 同时开时,同一 TP 组内必须关闭参数分片 ,否则一次 MatMul 要跨 ZeRO 组做 All-Gather,延迟爆炸
  • DP 的本质是提升并行度,一般来说,DP 的目标是开启前后保证梯度更新是是一致的,实现时也是朝这个方向实现的,比如 DDP 或 Megatron 中,在聚合梯度时,都是按照 DP 求平均(先 all_reduce SUM,再除以 DP_size)
  • DP 的通信量不算太高,也可以跨机器实现

附录:Megatron 中 DP 之间聚合梯度是平均还是累加 ?

  • 和 DDP 中一样,Megatron 中 DP 之间的梯度聚合是分两步的:

    • 先调用 all_reduce 实现累加
    • 然后再调用除法(除以 DP_Size)实现平均
  • 简单代码阅读 github.com/NVIDIA/Megatron-LM/blob/main/megatron/training/training.py:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ...
    torch.distributed.all_reduce(
    val,
    group=mpu.get_data_parallel_group(with_context_parallel=True)
    )
    val /= torch.distributed.get_world_size(
    group=mpu.get_data_parallel_group(with_context_parallel=True)
    )
    loss_reduced[key] = val
    ...
  • 特别说明:如果是想做 Token 粒度的平均(每个样本的可学习 Token 数不一致),需要多维护一个 Token 数量的变量并执行一次 all_reduce 通信

    • 当然,为了实现与不做 DP 完全一致的效果,这里其实是应该对 Token 也做聚合,再做除法才行的

补充:DDP 中的 DP 间梯度聚合

  • DDP 中在 DP 间累积梯度后,做了平均,具体实现参见 github.com/pytorch/pytorch/blob/main/torch/csrc/distributed/c10d/reducer.cpp
    1
    2
    3
    4
    5
    // 取值与 DP_size 有关(注意: 这里的 size 就是 DDP 中的 world_size,也就是 DP_size)
    div_factor_ = process_group_->getSize();
    ...
    // 做除法
    bucket_view.div_(div_factor_);

不同并行配置下需要多少卡?

  • 一般来说,Megatron-LM 官方实现给的结论是,所有维度的并行相乘得到总的卡数
  • 部分框架实现下, 可以让 EP 复用 CP 或 DP 等, 实现 EP 不参与乘法得到总的卡数

VSCode——Debug使用笔记


整体说明

  • VSCode Debug 大型项目是有一定难度和门槛的

Debug 的前置准备

安装必要插件

  • 打开 VSCode,左侧栏扩展(快捷键Ctrl+Shift+X),搜索并安装:
    • Python(微软官方,核心插件)
    • Python Debugger(新版调试核心,微软官方)
    • 可选:Pylance(增强代码提示,大型项目必备)

确认 Python 解释器

  • 大型项目通常用虚拟环境,Debug 是从 terminal 中启动的,需要在 terminal 先配置好环境
  • 快捷键 Ctrl+Shift+P,输入 Python: Select Interpreter

初始化调试配置文件(launch.json)

  • VSCode 调试依赖 launch.json 配置,大型项目需自定义配置以适配项目结构,步骤如下:

  • 1)打开项目根目录(关键:必须打开根目录,而非单个文件)

  • 2)打开调试面板:左侧栏 运行和调试 (快捷键Ctrl+Shift+D), 点击 创建 launch.json 文件

  • 3)选择调试环境:弹出的下拉框中选 Python,再选 Python File(基础模板,后续修改)

    • 默认生成的 launch.json 在 .vscode 文件夹下
  • 4)自定义 launch.json(这一步是核心!适配大型项目),修改为适合大型项目的配置,示例如下(注释说明关键参数):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    {
    "version": "0.2.0",
    "configurations": [
    {
    "name": "Python: 项目主入口", // 配置名称,可自定义
    "type": "debugpy", // 调试器核心,固定值
    "request": "launch", // 启动调试(而非附加进程)
    "program": "${workspaceFolder}/src/main.py", // 项目主入口文件(替换为你的实际路径)
    "cwd": "${workspaceFolder}", // 调试时的工作目录(固定为项目根)
    "args": ["--env", "dev", "--config", "configs/dev.yaml"], // 主程序运行参数(按需添加)
    "justMyCode": false, // 大型项目建议关闭,可调试第三方库/依赖代码
    "env": { // 自定义环境变量(如数据库地址、密钥等)
    "PYTHONPATH": "${workspaceFolder}", // 关键!解决大型项目模块导入问题
    "ENV": "development"
    },
    "envFile": "${workspaceFolder}/.env", // 加载.env文件(可选,管理环境变量)
    "stopOnEntry": false, // 启动后是否立即暂停(新手可设为true,熟悉后改false)
    "console": "integratedTerminal", // 调试输出到VSCode集成终端(方便看日志)
    "subProcess": true // 关键!调试子进程/子模块(大型项目多进程必备)
    },
    // 可选:添加调试单个模块/测试文件的配置
    {
    "name": "Python: 调试单个模块",
    "type": "debugpy",
    "request": "launch",
    "module": "src.utils.data_process", // 调试指定模块(替代program)
    "cwd": "${workspaceFolder}",
    "env": {"PYTHONPATH": "${workspaceFolder}"}
    }
    ]
    }
    • PYTHONPATH:将项目根目录加入 Python 路径,解决 模块找不到 问题(大型项目多目录结构必配);
    • subProcess:开启后可调试项目中通过 subprocess 启动的子进程;
    • args:传递给主程序的命令行参数(如配置文件路径、环境参数)

设置断点

  • 大型项目调试时应该避免 全局断点 ,需针对性设置:

基础断点

  • 点击代码行号左侧的空白处,出现红色圆点即断点生效(调试时运行到此处会暂停)

高级断点(非常好用)

  • 使用:右键断点红点 -> Edit Breakpoint,会出现多个选项可选,默认是 Expression
    • Expression :
      • 右键断点红点 -> Edit Breakpoint -> Expression -> 输入 Python 表达式(仅当表达式为 True 时暂停)
      • 示例:调试循环处理数据时,设条件 i == 100(仅第 100 次循环暂停,避免逐行调试)
      • 注意这个配置很好用,不需要修改代码,且可以是任意的语句
    • Log Messages :
      右键断点红点 -> Edit Breakpoint -> Log Messages -> 输入日志内容(如 "处理数据:{data_id}" )
      • 调试时不暂停,仅输出日志(适合排查循环/批量处理问题,不中断程序)

启动调试

  • 第一步:
    • 确认 launch.json 中选中目标配置
    • 比如调试面板顶部下拉框选 launch.json 中已经配置好的选项
  • 第二步:
    • 点击调试面板的 绿色三角按钮
    • 启动后程序运行到断点会暂停,顶部出现调试控制栏,核心按钮(从左到右):
  • 第三步:一些调试操作说明
    • 继续(F5):运行到下一个断点;
    • 单步跳过(F10):执行当前行,不进入函数内部(适合快速跳过无关代码);
    • 单步进入(F11):进入当前行调用的函数内部(调试子模块核心);
    • 单步退出(Shift+F11):从当前函数退出到调用处;
    • 重启(Ctrl+Shift+F5):重新启动调试;
    • 停止(Shift+F5):结束调试

附录:调试时查看数据

  • VSCode 提供多个面板 查看 查看变量/数据状态

变量面板

  • 自动显示当前作用域的所有变量(局部变量、全局变量、内置变量)
  • 可展开复杂对象(如字典、类实例)查看内部属性
  • 右键变量 -> 添加到监视 ,固定关注核心变量

监视面板

  • 手动输入 Python 表达式(如 len(data_list)、user.id == 123),实时显示结果;
  • 大型项目建议添加 核心状态变量 (如配置是否加载、数据库连接是否正常)
  • 监控面板的变量会固定长期展示(变化也会体现出来)

附录:调试大型项目的进阶技巧(避坑+效率提升)

技巧1:解决 模块导入失败 问题

  • 大型项目多目录结构(如 src/、tests/、configs/)易出现 ModuleNotFoundError,除了配置 PYTHONPATH,还可以尝试
    • 在项目根目录创建 __init__.py(空文件即可,标记为Python包);
    • 调试单个模块时,用 module 参数替代 program(如 launch.json 中 "module": "src.utils.data_process",而非直接指定文件路径)

技巧2:调试多线程/多进程项目

  • 多线程 :调试面板左侧 调用堆栈 -> 展开 线程 列表,切换不同线程查看状态;
  • 多进程 :
    • 若用 gevent 协程,需在 launch.json 中添加 "gevent": true
    • 普通进程使用 subProcess: true(子进程调试);
  • 进阶:使用 附加到进程 调试(调试面板 -> 添加配置 -> Python: 附加到进程 ,选择运行中的Python进程)

技巧3:调试测试用例(大型项目单元测试必备)

  • 安装 pytest(pip install pytest);

  • launch.json 添加配置:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    {
    "name": "Python: test case",
    "type": "debugpy",
    "request": "launch",
    "module": "pytest",
    "args": ["tests/test_data_process.py::test_handle_data", "-v"],
    "cwd": "${workspaceFolder}",
    "env": {"PYTHONPATH": "${workspaceFolder}"}
    }
    • 启动后直接调试指定测试用例(精准定位单元测试失败问题)

技巧4:跳过无关代码(提升效率)

  • 大型项目调试时避免进入第三方库/无关模块:
    • 在 launch.json 中设置 "justMyCode": true(默认),调试时自动跳过 site-packages 中的第三方库代码
    • 若需调试自己写的子模块,确保模块路径在 PYTHONPATH 中,且代码在 ${workspaceFolder} 下

附录:其他问题总结

  • 若断点未触发:检查 launch.json 的 program 路径是否正确、断点是否在执行路径上、PYTHONPATH 是否配置

  • 若变量查看异常:确认当前作用域是否正确(如函数内部只能看局部变量)

  • 若调试卡顿:减少不必要的断点,优先用 日志断点 替代普通断点

  • 断点灰色(未生效):

    • 原因:文件不在项目根目录、解释器选错、launch.json 的 program 路径错误;
    • 解决:确认打开的是项目根目录,重新选择解释器,检查 program 路径是否为 ${workspaceFolder} 开头
  • ModuleNotFoundError:

    • 解决:配置 PYTHONPATH: "${workspaceFolder}",或在代码开头添加:
      1
      2
      3
      import sys
      from pathlib import Path
      sys.path.append(str(Path(__file__).parent.parent)) # 向上级目录添加到路径
  • 调试时终端无输出:

    • 解决:launch.json 中设置 "console": "integratedTerminal"(而非 internalConsole)

VSCode——一些常见的问题解决方案

本文总结一些 VSCode 使用过程中遇到的问题和解决方案


VSCode 不显示 Git 修改情况

  • VSCode 不显示 Git 修改情况(比如行号旁的颜色标记、文件状态图标、源代码管理面板无内容等),通常是 Git 配置、工作区设置或插件冲突 导致的

第一步:基础检查:确认项目已关联 Git 仓库

  • VSCode 仅对 Git 仓库目录 显示修改跟踪,先确认项目是否初始化 Git
  • 执行命令 git status

第二步:启用 VSCode 内置 Git 功能(核心步骤)

  • VSCode 内置 Git 支持,可能被手动禁用,需重新启用:
    • 1)打开 VSCode 设置
    • 2)搜索配置项 git.enabled ,确保勾选(值为 true)
    • 3)搜索配置项 git.decorations.enabled ,确保勾选(控制行号旁的修改标记、文件图标状态)
    • 4)重启 VSCode(关键!修改配置后需重启生效)

第三步:检查 Git 可执行文件路径(Git 未被 VSCode 识别)

  • 若 VSCode 找不到 Git 程序,会无法跟踪修改,需手动指定 Git 路径
  • 先确认本地已安装 Git(终端执行 git --version,若提示“不是内部命令”,需先安装)
  • 在 VSCode 设置中搜索/创建 git.path
    • 注意,这个字段可能找不到,需要在 settings.json 文件中手动加入
    • 比如添加 "git.path": "/usr/bin/git"
      • Windows:默认 C:\Program Files\Git\bin\git.exe 或 C:\Program Files\Git\cmd\git.exe;
        • Mac/Linux:默认 /usr/bin/git 或 /usr/local/bin/git(可通过 which git 命令查询);
  • 重启 VSCode,再查看是否生效

其他可能的问题

  • Git 版本过低:VSCode 对旧版 Git 兼容性较差,升级 Git 到 2.20+ 版本(官网下载最新版);
  • 权限问题:项目目录或 .git 文件夹无读写权限
    • Windows 右键目录 -> 属性 -> 安全 -> 允许“完全控制”;
    • Mac/Linux 执行 chmod -R 755 项目目录;
  • VSCode 版本过旧:升级 VSCode 到最新版(左下角齿轮 -> 检查更新)
  • 冲突插件或 VSCode Git 配置错误

附录:修复文件/文件夹的 Git 跟踪状态(仅部分文件不生效时)

  • 若部分文件不显示修改,可能是 Git 未跟踪或被忽略
  • 检查 .gitignore 文件:确保目标文件没有被添加到 .gitignore(比如 node_modules/、dist/ 等目录会被默认忽略,修改这些目录的文件不会显示跟踪);
  • 手动跟踪未跟踪文件:终端执行 git add 文件名(或 git add . 跟踪所有文件),之后修改文件会显示红色(删除)、绿色(新增)、黄色(修改)标记;
  • 清除 Git 缓存(若文件曾被 .gitignore 忽略后需重新跟踪)
    1
    2
    3
    4
    5
    git rm --cached 文件名  # 单个文件
    # 或所有文件
    git rm -r --cached .
    git add .
    git commit -m "修复 Git 跟踪状态"

快捷键修改

  • File -> Preferences -> Keyboard Shortcuts
  • 可按照快捷键或名字搜索即可
    • 名称:
      • 如 前进/后退(中文)或 go back / go forward 表示前进或后退
      • 如 缩进/减少缩进 或 indent / outdent 表示缩进或者减少缩进
    • 快捷键:
      • 如 ctrl, cmd, tab, space,shift 等

Python——uv工具的使用


整体说明

  • uv 是一个快速的 Python 包管理器和项目管理工具,由 Astral 公司开发,旨在替代 pip、venv 等工具,提供更快的安装速度和更简洁的使用体验
  • uv 通常比 pip 快 10-100 倍
  • uv 内置虚拟环境:无需单独管理虚拟环境
  • uv 支持项目管理:原生支持 pyproject.toml,详情见附录
  • uv 保持了与 pip 相似的命令行接口,对于熟悉 pip 的用户来说很容易上手,同时提供了更现代、更高效的功能

安装 uv

  • 安装 uv 工具:

    1
    2
    3
    4
    5
    # 使用 pip 安装
    pip install uv

    # 或者使用官方安装脚本(推荐)
    curl -LsSf https://astral.sh/uv/install.sh | sh
  • 安装完成后,可以通过 uv --version 验证是否安装成功

  • 若提示没有命令,可能是需要配置环境变量,将下面的命令添加到 ~/.bashrc 中即可:

    1
    source $HOME/.local/bin/env

uv 基本用法介绍

虚拟环境管理

  • uv 内置了虚拟环境管理功能,无需单独使用 venv 或 virtualenv:

    1
    2
    3
    4
    5
    6
    7
    # 创建并激活虚拟环境(会在当前目录创建 `.venv` 文件夹)
    uv venv
    source .venv/bin/activate # Linux/macOS 激活环境,切换到当前环境下
    deactivate # Linux/macOS 退出激活

    # 直接在虚拟环境中运行命令(无需手动激活)
    uv run python --version
  • 若使用 source .venv/bin/activate 激活环境

    • 像 conda 一样,会切换到指定的虚拟环境下,直接使用 which python 可访问到当前项目的 python 文件
    • 但此时 pip 不会像 conda 一样替换,还是需要使用 uv pip 来使用,直接使用 which pip 得到的还是通用的 pip

IDEA 环境配置

  • 在使用 uv venv 创建了虚拟环境以后,可以使用 IDEA 直接选择 ./.venv/bin/python 作为解释器

类似 pip 的包安装与管理

  • uv 可以像 pip 一样安装和管理 Python 包:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    # 安装包
    uv pip install requests

    # 安装特定版本的包
    uv pip install requests==2.31.0

    # 从requirements.txt安装
    uv pip install -r requirements.txt

    # 升级包
    uv pip install --upgrade requests

    # 卸载包
    uv pip uninstall requests

    # 查看已安装的包
    uv pip list

    # 导出依赖到requirements.txt
    uv pip freeze > requirements.txt

uv 运行 python 文件

  • 使用 uv run 可以在虚拟环境中直接运行命令,无需手动激活环境 :
    1
    2
    3
    4
    5
    6
    7
    8
    # 运行Python解释器
    uv run python

    # 运行脚本
    uv run script.py

    # 运行命令行工具(如pytest)
    uv run pytest tests/

附录:uv 高级功能

缓存管理

  • uv 具有高效的缓存机制,可以手动管理缓存:
    1
    2
    3
    4
    5
    # 清理缓存
    uv cache clean

    # 查看缓存大小
    uv cache size

配置镜像源

  • uv 可以配置自己的 pip 源,配置国内镜像源加快下载速度,比如:

    1
    2
    # 设置 PyPI 镜像源
    export UV_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple/
    • 注:也可以永久添加到环境变量中方便使用
  • 临时指定镜像源的方式为:

    1
    uv add <package> --index-url https://pypi.tuna.tsinghua.edu.cn/simple/
  • 安装时输出源信息:

    1
    uv add requests --verbose # 注意:谨慎打开 `--verbose` 这个参数,会输出特别长的日志

构建和发布包

  • uv 支持构建和发布 Python 包到 PyPI:
    1
    2
    3
    4
    5
    # 构建包
    uv build

    # 发布包到 PyPI
    uv publish

附录:uv 管理 python 项目

  • uv 支持现代 Python 项目管理,包括 pyproject.toml:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # 初始化新项目(创建 pyproject.toml)
    uv init my_project # 在当前目录下创建 my_project 文件夹并生成基本文件
    # 生成 README.md main.py pyproject.toml 等文件
    cd my_project

    # 添加依赖(会更新 pyproject.toml)
    uv add requests # 生产依赖,将 requests 添加到 pyproject.toml 的 dependencies 列表中同时安装 requests 及其依赖(注:requests 的依赖不会添加到 pyproject.toml 中)
    uv add --dev pytest # 开发依赖,仅开发阶段需要使用到的依赖(将 pytest 添加到 pyproject.toml 的 dev 列表中),pytest 就是最常见的开发依赖,prod 环境不需要

    # 安装项目依赖(根据 pyproject.toml)
    uv sync # 补充

    # 运行项目中的脚本
    uv run my_script.py

补充:pyproject.toml 介绍

  • pyproject.toml 是现代 Python 项目的核心配置文件(TOML 格式)
    • 由 PEP 517/518/621 标准化
    • 可 替代传统的 setup.py/setup.cfg/requirements.txt
    • 实现统一管理项目构建、依赖、工具与元数据
pyproject.toml 的核心作用
  • 构建系统声明 :指定项目用什么工具构建(如 setuptools/hatch),解决“如何打包”的问题

    1
    2
    3
    [build-system]
    requires = ["setuptools>=61.0"]
    build-backend = "setuptools.build_meta"
  • 项目元数据 :定义项目名、版本、作者、描述、入口点等,用于发布与识别

  • 依赖管理 :声明运行/开发依赖(替代 requirements.txt),支持版本约束与分组

    1
    2
    3
    4
    [project]
    dependencies = ["torch>=2.0", "numpy"]
    [project.group.dev]
    dependencies = ["pytest", "black"]
  • 工具配置 :存放 uv/poetry/pytest 等工具的专属配置([tool.xxx])

  • 注:这 相当于 Node.js 的 package.json ,是项目的“配置中枢”

uv run xx.py 在执行什么

  • uv run xx.py 是 uv 工具的脚本执行命令 ,核心是在 uv 管理的隔离环境中运行 Python 脚本 ,背后做 3 件事:
    • 1)环境准备 :读取 pyproject.toml/uv.lock,确保依赖已安装(自动执行 uv sync 逻辑),并激活对应虚拟环境
    • 2)脚本执行 :调用 Python 解释器运行 xx.py,等价于 uv run python xx.py
    • 3)参数透传 :脚本后的所有参数直接传给 xx.py,和原生 python 一致
  • 相当于传统 Python 项目的什么命令
    uv 命令 传统 Python 等价操作(手动流程) 说明
    uv run xx.py 1. 激活虚拟环境(source venv/bin/activate)
    2. python xx.py
    uv 自动完成环境激活与依赖校验
    uv run python xx.py python xx.py(已激活虚拟环境) 完全等价
    uv run --frozen xx.py 跳过依赖检查,直接运行 对应部署场景的快速执行
  • TLDR: uv run xx.py ≈ 自动激活虚拟环境 + python xx.py ,省去手动管理虚拟环境的步骤

Python——OrderedDict类的使用


整体说明

  • OrderedDict 是 Python 标准库中的一个类,它位于 collections 模块下
  • 相对于普通字典,OrderedDict 能够记住元素插入的顺序,在迭代时,元素会按照插入的先后顺序被返回
  • OrderedDict 类对象的主要特点有:
    • 仍然是一个字典 :即仍然是 Key-Value 结构,且 Key 值不能重复
    • 保持插入顺序 :迭代时,元素会按照插入的顺序返回
    • 顺序敏感 :如果两个 OrderedDict 包含相同内容,但元素插入顺序不同,它们会被视为不相等
    • 支持移动操作 :可以通过 move_to_end() 方法将元素移动到开头或末尾
    • 删除操作保留顺序 :删除元素后,剩余元素的顺序保持不变

OrderedDict 的基本用法

  • OrderedDict 的一些常见操作示例:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    from collections import OrderedDict

    od = OrderedDict()
    od['a'] = 1
    od['b'] = 2
    od['c'] = 3
    od['b'] = 10

    # 迭代时保持插入顺序
    for key, value in od.items():
    print(key, value) # 输出: a 1, b 10, c 3

    print('---')
    # 移动元素到开始
    od.move_to_end('b', last=False)
    for key, value in od.items():
    print(key, value) # 输出: b 10, a 1, c 3

    print('---')
    # 移动元素到末尾
    od.move_to_end('b', last=True)
    for key, value in od.items():
    print(key, value) # 输出: a 1, c 3, b 10

    print('---')
    # 删除元素后结果不变
    del od['c']
    for key, value in od.items():
    print(key, value) # 输出: a 1, b 10

比较:与普通字典的区别

  • 在 Python 3.7 及以后的版本中,普通字典也会保持插入顺序,但 OrderedDict 仍然有其独特优势:
    • 明确的顺序语义 :使用 OrderedDict 可以更清晰地表达代码对顺序的依赖
    • 支持顺序相关的方法 :如 move_to_end()、popitem(last=False) 等,且这两个函数都可以通过 last 参数指定是操作第一个还是最后一个
    • 顺序敏感的比较 :两个字典即使包含元素相同,但元素顺序不同也会被视为不等

Math——证明笔记-对数似然的梯度期望为零


证明目标(对数似然的梯度期望为零)

  • 证明恒等式
    $$
    \mathbb{E}_{z \sim m_\theta(\cdot|x)} \left[ \nabla_\theta \log m_\theta(z \mid x) \right] = 0,
    $$
  • 这个恒等式是对数似然梯度的期望为零的性质,是强化学习和变分推断中的一个基本结果

证明过程

符号定义

  • 给定输入 \( x \),模型输出一个概率分布 \( m_\theta(z \mid x) \)(对离散 \( z \) 是概率质量函数,对连续 \( z \) 是概率密度函数)
  • 我们有归一化条件(离散):
    $$
    \sum_z m_\theta(z \mid x) = 1
    $$
  • 或(连续)
    $$
    \int_z m_\theta(z \mid x) , dz = 1
    $$

期望的定义

  • 对于连续情况(离散类似):
    $$
    \mathbb{E}_{z \sim m_\theta(\cdot|x)} \left[ \nabla_\theta \log m_\theta(z \mid x) \right]
    = \int_z m_\theta(z \mid x) \cdot \nabla_\theta \log m_\theta(z \mid x) , dz
    $$

代入梯度对数项

  • 因为
    $$
    \nabla_\theta \log m_\theta(z \mid x) = \frac{\nabla_\theta m_\theta(z \mid x)}{m_\theta(z \mid x)},
    $$
  • 所以:
    $$
    m_\theta(z \mid x) \cdot \nabla_\theta \log m_\theta(z \mid x) = \nabla_\theta m_\theta(z \mid x)
    $$
  • 于是期望变成:
    $$
    \int_z \nabla_\theta m_\theta(z \mid x) , dz
    $$

交换梯度与积分

  • 如果 \( m_\theta(z \mid x) \) 对 \( \theta \) 足够光滑,且积分与梯度可交换(通常成立),则:
    $$
    \int_z \nabla_\theta m_\theta(z \mid x) , dz
    = \nabla_\theta \int_z m_\theta(z \mid x) , dz
    $$

利用归一化条件

  • 归一化条件下
    $$
    \int_z m_\theta(z \mid x) , dz = 1 \quad \Rightarrow \quad \nabla_\theta 1 = 0
    $$
  • 因此:
    $$
    \mathbb{E}_{z \sim m_\theta(\cdot|x)} \left[ \nabla_\theta \log m_\theta(z \mid x) \right] = 0
    $$

附录:恒等式的直观解释

  • \( \nabla_\theta \log m_\theta(z \mid x) \) 称为 score function
  • 它的期望为零,是因为概率分布的总概率必须保持为 1
    • 改变参数 \(\theta\) 时,概率质量在不同 \(z\) 间重新分配,但增加某些地方的概率必然减少其他地方的概率,平均起来“变化方向”的期望为零
  • 这个性质在 REINFORCE 算法中用于引入基线(baseline)而不引入偏差,因为对任意只依赖 \(x\) 而不依赖 \(z\) 的 \(b(x)\):
    $$
    \mathbb{E} \left[ b(x) \cdot \nabla_\theta \log m_\theta(z \mid x) \right]
    = b(x) \cdot \mathbb{E} \left[ \nabla_\theta \log m_\theta(z \mid x) \right] = 0
    $$

NLP——LLM排行榜


整体说明

  • 目前,大模型(如LLM、多模态模型等)的评测和排名主要通过一些权威的基准测试和第三方平台进行
  • 本文记录并持续更新一些常见的在线排名网站和评测平台,涵盖不同领域的模型能力评估

LMSYS Chatbot Arena(LMArena)

整体介绍

  • 链接:https://lmarena.ai/
  • 领域:通用大模型排名
  • 基于人类反馈的实时对战排名(如 GPT-4、Claude、Gemini 等)
  • 采用 Elo 评分机制,反映用户偏好
  • 包含闭源模型
  • Chatbot Arena LLM Leaderboard: Community-driven Evaluation for Best LLM and AI chatbots
  • LmArena(原LMSYS)是一个由加州大学伯克利分校SkyLab和LMSYS研究团队开发的开源平台,专注于通过众包方式评估和比较不同AI模型的性能
  • LMArena 是目前大家最相信的人类偏好排行榜

文本子榜详细介绍

  • 对于 文本子榜,LMArena 会报告两种分数:
    • 基础分(wo style control):arena.ai/zh/leaderboard/text/overall-no-style-control
      • 基于模型对战,人类原始打分结果得到的 Elo Rating 分(不做任何修改)
    • 风格分(w style control):arena.ai/zh/leaderboard/text/overall
      • 默认是打开 Style Control 的形式:https://arena.ai/zh/leaderboard/text
      • Style Control 是指在 基础分 的基础上,通过一些消偏模型将模型的回复长度、格式等对齐后得到的 “回复内容” 本身的得分
    • 实践中,基础分和风格分的相对值可以看出一个模型风格的好坏来
      • 如果一个模型的 基础分 > 风格分,说明模型风格不错(比如回复较短)
      • 如果一个模型的 风格分 > 基础分,说明模型回复可能风格不行(比如回复偏长)
  • 从之前的经验看,LMArena 对战并不是严格遵循相似能力模型对战,而是更多的让部分模型参战(比如靠前的 Gemini 系列/Claude 系列等的参战频率就比较高),至少看着模型的 vote 数量是不完全对齐的
  • LMArena 有很多细分的榜单,比如 Text 榜单下还有类似 Arena Hard V2 中提到的 Hard Prompts 榜单和 Creative Writing 榜单等

文本子榜 AutoEval & 人工测评

  • 可以提交自己的模型(付钱)让对方进行打分(提交包括模型名称,URL,API Key 等信息即可),AutoEval 提交后大概几个小时可以得到结果,一般包含三个文件:
    • autoeval_leaderboards__{model_name}__xxx.html: 包含参与本次对战的模型整体评分
    • autoeval_report__{model_name}__xxx.html: 包含参与本次对战的报告细节分数
    • {model_name}__1.jsonl: 包含本次对战的 Prompt 和 Response 详细细节
  • 人工测评:将模型真实部署到线上共人类真实响应,需要的时间较久,收费也更高
  • 注:不同榜单的收费也不一样

OpenCompass

  • 链接:https://rank.opencompass.org.cn/home
  • 领域:通用大模型排名、多模态模型排名、对战排名均有
  • 包含豆包、Qwen、DeepSeek等
  • 司南 OpenCompass 是由上海人工智能实验室(Shanghai AI Lab)推出的一个开源、中立、全面的 LLM 评测体系,旨在对各类大模型进行系统性、标准化的能力评估与排名

LiveCodeBench

  • 链接:https://livecodebench.github.io/leaderboard.html
  • 领域:代码能力排名

Open LLM Leaderboard (Hugging Face)

  • 链接:https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard
  • 领域:通用大模型排名
  • 评估开源大模型在多项任务(如ARC、HellaSwag、MMLU等)上的表现
  • 涵盖模型:LLaMA、Falcon、Mistral等诸多模型,还有许多名字不出名的是基于其他模型微调后改名的
  • 仅评估开源模型

Stanford HELM (Holistic Evaluation of Language Models)

  • 链接:https://crfm.stanford.edu/helm/
  • 领域:通用大模型排名
  • 斯坦福的全面评测框架,覆盖准确性、公平性、鲁棒性等维度
  • 其中可选很多评估标注,比如MMLU,Finance等

C-Eval (中文评测基准)

  • 链接:https://cevalbenchmark.com/static/leaderboard.html
  • 领域:中文测评
  • 评估中文知识、推理能力的测试集,涵盖52个学科
  • 排名包含:GPT-4、ChatGLM、通义千问等

SuperCLUE (中文通用大模型评测)

  • 链接:https://www.superclueai.com/
  • 领域:中文测评
  • 中文版综合性评测,包括基础能力、专业任务等

MMBench

  • 链接:https://mmbench.opencompass.org.cn/leaderboard
  • 领域:多模态模型排名
  • 评估图文理解、生成能力的基准(如GPT-4V、Gemini Vision)

GLUE/SuperGLUE

  • 链接:https://gluebenchmark.com/
  • 领域:自然语言理解
  • 经典NLU任务评测,但近年逐渐被更大基准取代,都是一些比较老的模型评估

NLP——WizardLM(Evol-Instruct)

注:本文包含 AI 辅助创作

  • 参考链接:
    • 原始论文:(Evol-Instruct)WizardLM: Empowering large pre-trained language models to follow complex instructions, Microsoft & PKU, arXiv 20230424, 20230610, 20250527
    • 相关 GitHub 地址:github.com/nlpxucan/evol-instruct

Paper Summary

  • 整体说明:
    • 论文提出了一种为 LLM 生成多样化和复杂指令数据的进化算法 Evol-Instruct(使用 LLM 而非人类来创建大量不同复杂度指令数据的途径),并基于此数据集微调得到了 LLaMA(得到 WizardLM)
    • WizardLM 在一系列公认的基准测试中显著超越了典型的开源 LLM,如 Alpaca 和 Vicuna
    • WizardLM 在代码、数学、GPT-4 和人工评估方面均以显著优势超越基线模型
  • 背景 & 问题:
    • 使用开放域指令跟随数据训练 LLM 已经取得了巨大成功
    • 问题1:人工创建此类指令数据非常耗时且劳动密集
    • 问题2:人类可能难以生成高复杂度的指令
  • 基本思路:从一个初始指令集出发,论文使用提出的 Evol-Instruct 方法逐步将其重写为更复杂的指令
  • 模型训练:论文将所有生成的指令数据混合以微调 LLaMA(论文将得到的模型称为 WizardLM)
    • 自动评估和人工评估均一致表明, WizardLM 的性能优于基线模型,如 Alpaca(基于 Self-Instruct 训练)和 Vicuna(基于人工创建的指令训练)
    • 论文通过实验结果证明:由 Evol-Instruct 精心构建的指令跟随数据集的质量能够显著提升 LLM 的性能

Introduction and Discussion

  • LLM 已成为众多自然语言处理任务的首选方法 (2020; 2022; 2023)
  • LLM 在大规模文本数据上进行训练以预测后续 Token ,使其能够针对各种输入生成连贯流畅的文本
  • 然而,这些模型通常难以遵循用户指定的指令或目标,这限制了它们在现实场景中的实用性和适用性
  • NLP 界近期见证了众多努力,旨在训练 LLM 更好地遵循指令并变得更有帮助 (2023;)
    • 训练指令跟随语言模型的初步尝试 (2022; 2021; ) 基于一系列不同的 NLP 任务集合,并辅以少量手写指令
  • 这些封闭域指令存在两个主要缺点:
    • 首先,一个 NLP 数据集中的所有样本仅共享少数几个常见指令,严重限制了其多样性;
    • 其次,指令通常只要求完成一项任务 (但在现实生活中,人类的指令通常具有多个且多样的任务需求)
  • 通过使用真实用户生成的开放域指令数据,OpenAI 的 LLM(例如 InstructGPT (2022) 和 ChatGPT)取得了巨大成功
    • 这些开放域指令能够充分释放 LLM 的无限潜力 (2023; ),并使它们能够执行更复杂多样的任务
  • 但像 OpenAI 那样使用人类创建开放域指令数据集会遇到以下挑战:
    • 整个标注过程极其昂贵且耗时 (2023; )
    • 人工创建指令的难度级别分布偏向于简单或中等,困难指令较少(根据图 5a 中 ShareGPT (2023) 的难度统计)
    • 人类标注者容易疲劳,无法持续高强度工作以产生足够比例的高难度指令 (2023; )
  • 基于这些问题,开发一种能够以相对较低成本大规模自动生产开放域指令(尤其是更困难的指令)的方法,成为进一步推进指令微调语言模型(instruction-tuned language models)的关键 (2023; )
  • 在这项工作中,论文引入了 Evol-Instruct ,一种使用 LLM 而非人类来自动大规模生成不同难度级别开放域指令的新方法,以提升 LLM 的性能
  • 图 1 展示了 Evol-Instruct 的运行示例
  • 从一个简单的初始指令 “1+1=?” 开始,论文的方法随机选择深度演化(In-depth Evolving)(蓝色方向线)或广度演化(In-breadth Evolving)(红色方向线)来将简单指令升级为更复杂的指令或创建新指令(以增加多样性)
    • 深度演化包括五种操作类型:添加约束(add constraints)、深化(deepening)、具体化(concretizing)、增加推理步骤(increase reasoning steps)和复杂化输入(complicate input)
    • 广度演化是突变(mutation) ,即基于给定指令生成一个全新的指令
    • 这六种操作通过使用特定的提示词(prompt)来提示(prompting)一个 LLM 来实现
  • 由于演化后的指令是由 LLM 生成的,有时演化会失败
    • 论文采用一个指令淘汰器(instruction eliminator)来过滤失败的指令,这被称为淘汰演化(Elimination Evolving)
    • 论文重复这个进化过程若干轮,以获得包含各种复杂度的足够指令数据
  • 为了验证 Evol-Instruct 的有效性以及它创建的用于微调的指令是否超越人类创建的指令
    • 论文演化来自 Alpaca (2023) 数据(由机器创建)的指令,微调 LLaMA (2023) 模型,并全面比较微调后的模型 WizardLM 与在 ShareGPT(指令由人类创建)上训练的 Vicuna (2023)
      • Alpaca 数据总共有 \(52k\) 个样本,是使用 self-instruct (2022a) 从仅 \(175\) 个人工创建的种子指令生成的
      • 论文选择 Alpaca 数据作为演化的初始数据,这可以确保 WizardLM 的训练指令几乎没有人直接参与标注
    • 论文使用 OpenAI ChatGPT API 执行了四轮演化 ,最终获得 \(250k\) 条指令
    • 为了与 Vicuna 的 \(70k\) 真实用户数据进行公平比较
      • 论文从完整的 \(250k\) 数据中采样了 \(70k\) 条指令 ,并微调了 LLaMA 13B 模型
    • 由于原始 Alpaca 数据只有 \(52k\) 个样本,论文使用其 self-instruct 方法生成了额外的 \(18k\) 数据,并使用其代码重新训练了 LLaMA 13B 模型,得到 Alpaca 13B 作为论文的基线
    • 由于先前指令跟随测试数据集中困难指令比例较低 ,论文手动创建了一个新的难度平衡的测试数据集 ,命名为 WizardEval
  • 论文在广泛的 LLM 基准测试(涵盖推理、代码、数学、通用对话等)上评估了 Alpaca、Vicuna、ChatGPT 和 WizardLM
  • 论文的主要发现如下:
    • 论文引入了 Evol-Instruct ,一种通过自动大规模生成各种主题和难度级别的开放域指令来大幅提升开源 LLM 性能的新方法
    • 论文开发了 WizardLM 模型,其在一系列基准测试中显著超越了典型的开源 LLM,如 Alpaca 和 Vicuna
      • WizardLM 在代码、数学、GPT-4 和人工评估方面均以显著优势优于基线模型
    • 论文进行了一项初步研究,强调了指令复杂度在监督微调大规模预训练语言模型中取得出色性能的重要性

Approach

  • 本节将详细阐述所提出的 Evol-Instruct 的细节
  • 如图 2 所示,该流程主要包含两个组件:
    • 指令演化器(Instruction Evolver)
    • 指令淘汰器(Instruction Eliminator)
  • 这些组件的细节将在第 3.2 节中介绍,指令微调方法将在第 3.3 节中描述

Definition of Instruction Data Evolution(指令数据演化)

  • 论文从给定的初始指令数据集开始演化:
    $$D^{(0)}=(I_{k}^{(0)},R_{k}^{(0)})_{1\leq k\leq N}$$
    • 其中 \(I_{k}^{(0)}\) 是 \(D^{(0)}\) 中的第 \(k\) 条指令
    • \(R_{k}^{(0)}\) 是第 \(k\) 条指令的相应响应
    • \(N\) 是 \(D^{(0)}\) 中的样本数量
  • 在每次演化中,论文通过使用 Evol-Instruct 提示词提示(prompting)一个 LLM
    • 将 \(D^{(t)}\) 中的所有 \(I^{(t)}\) 升级为 \(I^{(t+1)}\),然后使用该 LLM 为新演化出的 \(I^{t+1}\) 生成相应的响应 \(R^{t+1}\)
    • 从而,论文获得一个演化后的指令数据集 \(D^{t+1}\)
  • 通过迭代执行 \(M\) 次演化,我们可以顺序获得 \(M\) 个演化数据集:
    $$[D^{(1)}\cdots D^{(M)}]$$
  • 论文的工作专注于开放域指令数据,其中指令具有变化的输入和任务,指令部分和输入部分之间没有明确的区分

Automatic Instruction Data Evolution

  • 论文的指令演化流程包括三个步骤:
    • 1) 指令演化(instruction evolving)
    • 2) 响应生成(response generation)
    • 3) 淘汰演化(elimination evolving),即过滤未能成功演化的指令
Instruction Evolution
  • 论文发现 LLM 可以使用特定的提示词使给定的指令变得更加复杂和困难。此外,它们可以生成完全全新、复杂度相当但完全不同的指令。利用这一发现,我们可以迭代地演化一个初始指令数据集,提高其难度级别并扩展其丰富性和多样性。论文使用给定的初始指令数据集 \(D^{(0)}\) 初始化指令池(instruction pool)。在每个演化轮次(epoch)中,从前一轮次升级的指令被从池中取出。然后论文利用指令演化器(instruction evolver)来演化每个取出的指令,并利用指令淘汰器(instruction eliminator)来检查演化是否失败。成功演化的指令被添加到池中,而不成功的指令则原样放回,希望在下个演化轮次中能成功升级它们
Instruction Evolver
  • 指令演化器是一个使用 Evol-Instruct 提示词来演化指令的 LLM,有两种类型:深度演化和广度演化
In-Depth Evolving
  • 通过五种类型的提示词来增强指令,使其更复杂和困难:

    • 添加约束(add constraints)、深化(deepening)、具体化(concretizing)、增加推理步骤(increased reasoning steps)和复杂化输入(complicating input)
  • 深度演化提示词的核心部分是“您的目标是将给定的提示词重写为一个更复杂的版本,以使那些著名的 AI 系统(例如 ChatGPT 和 GPT4 (OpenAI, 2023))更难处理。但重写后的提示词必须是合理的、可被人类理解并回应”

  • 论文要求 LLM 创建具有挑战性但合理且非 AI 任意想象的指令

  • 需要逐步增加难度以避免指令集中充斥极其复杂的指令,这会损害训练模型的泛化性能

  • 为了控制难度增加,论文使每次演化“更难一点”,并限制最多添加 10 到 20 个单词

  • 在上述五种演化中,除了复杂化输入(complicating input)外,其他都可以在没有任何上下文示例(in-context examples)的情况下实现

  • 论文展示添加约束的提示词如下(深化、具体化和增加推理步骤的提示词将在附录 A-C 中详述)

  • 示例 3.1:深度演化中添加约束的提示词(Prompt for Adding Constraints of In-Depth Evolving)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    I want you act as a Prompt Rewriter.
    Your objective is to rewrite a given prompt into a more complex version to make those famous AI systems (e.g., ChatGPT and GPT4) a bit harder to handle. But the rewritten prompt must be reasonable and must be understood and responded by humans.
    Your rewriting cannot omit the non-text parts such as the table and code in #Given Prompt#:. Also, please do not omit the input in #Given Prompt#.
    You SHOULD complicate the given prompt using the following method:
    **Please add one more constraints/requirements into #Given Prompt#**
    You should try your best not to make the #Rewritten Prompt# become verbose, #Rewritten Prompt# can only add 10 to 20 words into #Given Prompt#. ‘#Given Prompt#’, ‘#Rewritten Prompt#’, ‘given prompt’ and
    ‘rewritten prompt’ are not allowed to appear in #Rewritten Prompt#
    #Given Prompt#:
    {Here is instruction.} #Rewritten Prompt#:

    我希望您扮演一个提示词重写器(Prompt Rewriter)
    您的目标是将给定的提示词重写为一个更复杂的版本,以使那些著名的 AI 系统(例如 ChatGPT 和 GPT4)更难处理。但重写后的提示词必须是合理的、可被人类理解并回应
    您的重写不能省略 #给定提示词# 中的非文本部分,例如表格和代码。同时,请不要省略 #给定提示词# 中的输入
    您**应该**使用以下方法使给定提示词复杂化:
    **请向 #给定提示词# 中添加一个更多的约束/要求**
    您应尽力避免使 #重写后的提示词# 变得冗长,#重写后的提示词# 只能在 #给定提示词# 的基础上增加 10 到 20 个单词。“#给定提示词#”、“#重写后的提示词#”、“给定提示词”和“重写后的提示词”不允许出现在 #重写后的提示词# 中
    **#给定提示词#:**
    {这里是指令。}
    **#重写后的提示词#:**
  • 对于复杂化输入(complicating input),论文将使用上下文演示(in-context demonstration)。由于演示较长,论文在下面提供一个简要模板,完整提示词详见附录 D

  • 示例 3.2:深度演化中复杂化输入的提示词(Prompt for Complicating Input of In-Depth Evolving)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    I want you act as a Prompt Rewriter.
    Your objective is to rewrite a given prompt into a more complex version to make those famous AI systems (e.g., ChatGPT and GPT4) a bit harder to handle. But the rewritten prompt must be reasonable and must be understood and responded by humans.
    You must add [XML data] format data as input data in [Rewritten Prompt]
    #Given Prompt#:
    {Here is instruction of Example 1.}
    #Rewritten Prompt#:
    {Here is rewritten instruction of Example 1.} ... N -1 Examples ...
    You must add [#Given Dataformat#] format data as input data in [Rewritten Prompt] #Given Prompt#:
    {Here is instruction of Example N.}
    #Rewritten Prompt#:

    我希望您扮演一个提示词重写器(Prompt Rewriter)
    您的目标是将给定的提示词重写为一个更复杂的版本,以使那些著名的 AI 系统(例如 ChatGPT 和 GPT4)更难处理。但重写后的提示词必须是合理的、可被人类理解并回应
    您必须在 [重写后的提示词] 中添加 [XML 数据] 格式的数据作为输入数据
    **#给定提示词#:**
    {这里是示例 1 的指令。}
    **#重写后的提示词#:**
    {这里是示例 1 重写后的指令。}
    ... N -1 个示例 ...
    您必须在 [重写后的提示词] 中添加 [#给定数据格式#] 格式的数据作为输入数据
    **#给定提示词#:**
    {这里是示例 N 的指令。}
    **#重写后的提示词#:**
In-Breadth Evolving
  • 广度演化旨在增强主题覆盖度、技能覆盖度以及整体数据集的多样性
  • 开放域指令微调数据集(例如 Alpaca、ShareGPT 等)通常规模较小,缺乏主题和技能多样性
  • 为了解决这个问题,论文设计了一个提示词,基于给定指令生成一个全新的指令,要求新指令更加长尾(more long-tailed)。论文的广度演化提示词如下:
  • 示例 3.3:广度演化的提示词(Prompt for In-Breadth Evolving)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    I want you act as a Prompt Creator.
    Your goal is to draw inspiration from the #Given Prompt# to create a brand new prompt.
    This new prompt should belong to the same domain as the #Given Prompt# but be even more rare.
    The LENGTH and difficulty level of the #Created Prompt# should be similar to that of the #Given Prompt#. The #Created Prompt# must be reasonable and must be understood and responded by humans.
    ‘#Given Prompt#’, ‘#Created Prompt#’, ‘given prompt’ and ‘created prompt’ are not allowed to appear in #Created Prompt#.
    #Given Prompt#:
    {Here is instruction.} #Created Prompt#:

    我希望您扮演一个提示词创建者(Prompt Creator)
    您的目标是从 #给定提示词# 中汲取灵感,创建一个全新的提示词
    这个新提示词应该与 #给定提示词# 属于同一领域,但应更加罕见(rare)
    #创建出的提示词# 的长度和难度级别应与 #给定提示词# 相似
    #创建出的提示词# 必须是合理的、可被人类理解并回应
    “#给定提示词#”、“#创建出的提示词#”、“给定提示词”和“创建出的提示词”不允许出现在 #创建出的提示词# 中
    #给定提示词#:
    {这里是指令。}
    #创建出的提示词#:
Response Generation
  • 论文使用与演化相同的 LLM 来为演化后的指令生成相应的响应
  • 生成提示词是 “{Here is instruction.}”,论文将其输入到 ChatGPT-3.5 的请求中,并将返回的文本正文解析为响应
Elimination Evolving(淘汰演化)
  • 论文将以下四种情况归类为指令演化失败:
    • 1)演化后的指令与原始指令相比未提供任何信息增益
      • 论文使用 ChatGPT 来进行此判断,详情请参阅附录 G
    • 2)演化后的指令使得 LLM 难以生成响应
      • 论文发现当生成的响应包含“抱歉(sorry)”且长度相对较短(即少于 80 个单词)时,通常表明 LLM 难以响应演化后的指令
      • 因此我们可以使用此规则进行判断
    • 3)LLM 生成的响应仅包含标点符号和停用词(stop words)
    • 4)演化后的指令明显复制了演化提示词中的某些词语

Finetuning The LLM On The Evolved Instructions

  • 所有演化完成后,论文将初始指令数据集与所有轮次中演化得到的指令数据合并,并对样本进行随机打乱,以创建用于微调的数据集
    • 这种处理方式确保了数据集中不同难度级别的指令均匀分布,从而最大化模型微调的平滑性
  • 为了证明性能提升并非源于合并后数据量的增加,而是源于论文提出的新方法 Evol-Instruct,论文从合并后的数据中随机抽取与训练基线模型(例如 Vicuna)等量的数据,作为论文最终的微调数据
  • 论文选择 Vicuna 的提示词(prompt)作为论文微调所用的提示词,其具体格式为:“A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user’s questions. USER: Hi ASSISTANT: Hello. USER: Who are you? ASSISTANT: I am WizardLM ……”

Experiment

  • 论文通过自动评估和人工评估两种方式对 WizardLM、Alpaca、Vicuna 和 ChatGPT 进行了评估

Baselines

  • (1) ChatGPT 是由 OpenAI 开发的一款 AI 聊天机器人,能够以自然且引人入胜的方式与用户互动
    • 它建立在 GPT-3.5 和 GPT-4 等 LLM 之上,并基于海量的互联网文本数据进行训练
  • (2) Alpaca 是由斯坦福大学开发的开源指令遵循模型
    • 为了公平比较,论文使用 Alpaca 采用的 Self-Instruct 方法将指令数量从 52k 扩展到 70k,并将原始的 David+003 响应替换为 ChatGPT 的响应
    • 论文基于这份新的 Alpaca 数据,从 LLaMA 13B (2023) 重新训练了 Alpaca 13B
  • (3) Vicuna 基于 LLaMA,并在从 ShareGPT 收集的 70k 用户共享对话上进行了微调
    • 它是目前最先进、最通用的开源指令遵循模型之一
    • 论文使用来自 FastChat 的 13B-v1.1 模型
  • (4) 基于 Llama 13B 训练的开源模型,包括 Baize (2023)、CAMEL (2023a) 和 Tulu (2023)

Experiment detail

  • 为了构建数据集,论文使用 Alpaca 的 \(52k\) 指令数据集进行初始化,并迭代执行 \(M\) 轮演化,其中 \(M=4\)
  • 在每一轮演化中,对于每条指令,论文以相等概率从总共六个演化提示(即五个来自深度演化,一个来自广度演化)中随机选择一个
    • 论文使用 Azure OpenAI ChatGPT API5 执行上述过程
    • 然后,论文利用 ChatGPT 生成响应
    • 最终,论文获得了 \(250k\) 条指令
  • 为了公平比较,论文从 \(250k\) 数据中以相等概率随机采样 \(70k\) 数据作为 WizardLM 的最终训练数据,与 Vicuna 的训练数据量相同
    • 论文使用温度为 1 来生成响应,并将生成的最大 token 数设置为 2048
    • 此外,论文将频率惩罚设置为零,top-p 设置为 \(0.9\)
    • 总共,论文请求 API \(52k\times 4\times 3=624k\) 次以构建完整的数据集
  • 论文使用预训练的 LLaMA 13B (2023) 来初始化论文的模型
    • 论文采用 Adam 优化器,初始学习率为 \(2\times 10^{-5}\),最大 token 数为 2048,每个 GPU 的批次大小为 4
  • 论文在 8 个 V100 GPU 上使用 Deepspeed Zero-3 训练了论文的模型 3 个 epoch ,耗时 140 小时
  • 对于推理,论文对 WizardLM 和基线模型使用贪心搜索,并将最大生成长度设置为 2048

Automatic Evaluation

  • 为了全面概述论文的 WizardLM 的性能,论文在多个 LLM 基准测试中对论文的模型与既定基线进行了比较
  • HuggingFace 的 OpenLLM 排行榜 :(2023) 包括 MMLU (2020)、ARC (2018)、HellaSwag (2019) 和 TruthfulQA (2022)
    • MMLU 包含一系列多项选择的学术问题
    • ARC 是一组小学科学问题
    • HellaSwag 是一个常识推理测试
    • TruthfulQA 衡量模型再现错误陈述的倾向
    • 论文采用了 OpenLLM 的评估代码 (2021)
  • 代码生成 (Code Generation)
    • 论文使用广泛使用的 HumanEval (2021) 基准测试,该测试包含 164 个编码问题,通过报告 pass@1 指标来评估 LLM 在函数级别的代码编写能力
  • 数学推理 (Math Reasoning)
    • 论文使用 GSM8k (2021) 来评估模型的数学能力,GSM8k 包含 1319 个小学数学测试数据
    • 论文采用 4-shot 测试并报告 pass@1
  • GPT-4 评估 (GPT-4 Evaluation)
    • 论文采用了两个广泛认可的 GPT-4 评估基准,包括 AlpacaEval (2023c) 和 MT-Bench (2023)
    • 论文还使用 GPT-4 在论文后续提出的 WizardEval 上评判 LLM
  • 如图 3 和表 1 所示,与其他相同规模的开源模型相比, WizardLM 在大多数基准测试中都具有显著的性能优势。特别是在数学、代码和 GPT-4 评估方面,它相比 Alpaca、Vicuna、Baize、CAMEL 和 Tulu 取得了显著提升

Human evaluation

  • 为了评估 WizardLM ,论文在论文精心制作的测试平台 WizardEval 上进行了人工评估,该测试集包含 218 条来自不同来源(如在线开源项目(Github, ShareGPT)、平台(Twitter)和论坛(Reddit, Discord)的真实世界人类指令
    • 数据包含 29 项技能和领域,代表了人类的主要需求,例如代码生成(Coding Generation)、Math、Reasoning、复杂格式(Complex Formats)、写作(Writing)、广泛学科(Extensive Disciplines)等
  • 如图 3(a) 和附录图 6 所示,论文还分别分析了 WizardEval 的难度和技能分布,这表明 WizardEval 能够处理比 Self-Instruct 和 Vicuna 测试集更复杂和要求更高的场景的评估
  • 论文在 WizardLM-13b 和基线模型之间进行了盲法成对比较
    • 论文招募了 10 名受过良好教育的标注员
    • 向每位标注员展示来自 Alpaca-13b、Vicuna-13b、 WizardLM 和 ChatGPT 的四条响应,这些响应被随机打乱以隐藏其来源
  • 然后,标注员根据以下标准(详细定义请参阅附录 K)判断哪个响应更好:
    • (1) 相关性(Relevance)
    • (2) 知识性(Knowledgeable)
    • (3) Reasoning
    • (4) 计算(Calculation)
    • (5) 准确性(Accuracy)
  • 然后,他们应将四个响应从 1 到 5 排名(1 表示最好),并允许对可比较的实例给出相同的分数
    • 为了估计胜率,论文比较了每对模型之间的获胜、失败和平局频率
  • 如图 4 (b) 所示
    • WizardLM 取得了比 Alpaca 和 Vicuna 好得多的结果,这证明了 Evol-Instruct 方法的有效性
    • 所有的 Kappa 分数均大于 0.6,这表明标注员之间具有良好的一致性

Ablation Study

  • 使用不同的数据(种子、大小)、演化模型和基础模型大小进行训练 (Training with different data (seed, size), evol model, and base model size)
    • 为了研究不同数据种子、演化模型、演化数据集规模、预训练模型对论文提出的方法的影响,论文进行了以下实验:
      • a)使用 70k ShareGPT 作为种子数据获得 WizardLM-13b (ShareGPT Seed);
      • b)使用 LlaMA-2-70B-Chat 替代 ChatGPT 作为演化执行模型获得 WizardLM-13b (LlaMA-2-70B-Chat Evol);
      • c)论文在更大规模的预训练模型 Llama-1 65B 和 Llama-2 70B 上训练,分别获得 WizardLM-65b 和 WizardLM-70b;
      • d)使用完整的 250k 演化数据获得 WizardLM-13b (250K);
      • e)使用与 LlaMA 系列完全不同的基础模型 Mistral-7B,获得 WizardLM-7b (Mistral);
      • f)为了比较更多样化的指令数据,论文选择 Supernatural Instructions (2022b) 并随机抽取 70k 数据训练 llama-13b 获得 LlaMA-13b (SNI)
    • 完整结果如表 2 所示:
      • 为了探究 WizardLM-13b (ShareGPT Seed) 在 GSM8k 上表现较差的原因,论文分别从 ShareGPT 和 Alpaca 数据中随机采样 2000 条指令,然后使用 ChatGPT 判断(提示词请参阅附录 G)一条指令是否与“数学”相关,论文发现 ShareGPT 仅包含 4.3% 的数学数据,而 Alpaca 数据包含 11.8% 的数学数据,因此作者认为较少的数学数据导致 WizardLM-13b (ShareGPT Seed) 的 GSM8k 性能较差
    • 表2结果表明:
      • (i) ShareGPT 是比 Alpaca 更好的 evol-instruct 种子;
      • (ii) 更大的演化数据规模可以提高模型能力;
      • (iii) 论文提出的 Evol-Instruct 方法不依赖于 ChatGPT,其他强大的开源模型如 Llama-2 也是 ChatGPT 的良好替代品;
      • (iv) 论文的演化数据也显示出比 Supernatural Instructions 更好的微调性能
      • 此外,在不同预训练基础(例如 Llama-1 65B、Llama-2、Mistral-7B)上的结果表明,论文的 Evol-Instruct 可以广泛应用于各种预训练模型
  • 深度演化分析 (Analysis of In-depth Evolving)
    • 图 4(a) 和 4(b) 展示了一项消融研究,调查了数据演化轮数的影响
    • 为了研究演化过程的深度,论文使用 ChatGPT 来判断指令的难度级别。使用的提示词请参阅附录 E
    • 图 4(b) 显示了使用每轮演化数据微调的模型在(第 4.3 节中的九个自动基准测试上的)平均分数
    • 从 \(C0\) 到 \(C4\) 的每轮数据大约为 \(52k\)
    • 从该图的趋势可以看出,随着训练指令数据复杂度的逐渐增加,微调模型的性能也同步提高
    • 为了探究 ChatGPT 难度评分的正确性,论文还使用 GPT-4 和人工来测量指令难度,附录 I 表 3 中的详细结果表明 ChatGPT、GPT-4 和人工标注员之间具有良好的一致性
  • 广度演化分析 (Analysis of In-breadth Evolving)
    • 论文旨在检查指令的语义广度
    • 论文使用 t-SNE (2008) 和 k-means (1979) 算法将指令的 BERT 嵌入划分为 20 个簇
    • 附录 F 中的图 6 显示了聚类情况,突出了论文的方法与 ShareGPT 和 Alpaca 相比具有更优越的分散性,表明论文的指令具有更大的主题多样性

Related Work

Closed domain instruction tuning

  • 早期的指令跟随训练工作 (2021; 2023) 关注 LM 的跨任务泛化能力,其中 LM 在广泛的公共 NLP 数据集上进行微调,并在不同的 NLP 任务集上进行评估
    • T5 (2020) 做出了最早的尝试,使用统一的文本到文本(text-to-text)格式共同训练自然语言处理(NLP)任务,如问答、文档摘要和情感分类
    • 诸如 FLAN (2021)、ExT5 (2022)、T0 (2022) 和 KnowDA (2022c) 等工作将 NLP 任务的数量增加到大约一百个,并为每个任务精心设计了几个指令 (2023;)
    • 诸如 ZeroPrompt (2022) 和 FLAN-T5 (2022) 等工作将任务数量提升至数千个
  • 这些研究一致表明,使用多样化的 NLP 任务指令微调 LM 可以增强它们在新任务上的性能
  • 但使用这些封闭形式指令(即指令通常仅针对单个 NLP 任务,且输入数据形式简单)训练的 LLM 在真实用户场景中往往表现不佳

Open domain instruction tuning

  • 论文的工作属于这一研究路线
  • OpenAI 雇佣了许多标注员并编写了许多带有相应正确答案的指令
    • 这些人工创建的指令形式多样,任务类型丰富
    • 基于这个数据集,OpenAI 将 GPT-3 (2020) 训练成 InstructGPT (2022),它可以处理各种真实用户指令,并导致了 ChatGPT 的成功
  • Orca (2023) 不仅学习来自 LLM 的表层响应文本,还捕获复杂的推理过程信号
  • 由于 OpenAI 的这些杰出工作并未开源,Alpaca (2023) 和 Vicuna (2023) 随后基于开源 LLM LLaMA (2023) 积极探索了开放域指令微调
  • Alpaca 使用了一个包含 \(50k\) 条指令的数据集,这些指令是从有限(例如 175 个样本)的手写指令种子集中生成的
  • 论文的工作与 InstructGPT 和 Vicuna 的不同之处在于:
    • 论文使用 AI 生成的数据进行指令微调
    • 与 Alpaca 的 self-instruct (2022a) 生成方法不同, Evol-Instruct 可以控制生成指令的难度和复杂度级别

附录 A:Deepening Prompt(深化 Prompt)

  • 示例 A.1:用于深度演化的深化提示 (Prompt for Deepening of In-Depth Evolving)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    I want you act as a Prompt Rewriter.
    Your objective is to rewrite a given prompt into a more complex version to make those famous AI systems (e.g., ChatGPT and GPT4) a bit harder to handle. But the rewritten prompt must be reasonable and must be understood and responded by humans.
    Your rewriting cannot omit the non-text parts such as the table and code in #Given Prompt#:. Also, please do not omit the input in #Given Prompt#.
    You SHOULD complicate the given prompt using the following method:
    If #Given Prompt# contains inquiries about certain issues, the depth and breadth of the inquiry can be increased.
    You should try your best not to make the #Rewritten Prompt# become verbose, #Rewritten Prompt# can only add 10 to 20 words into #Given Prompt#. ‘#Given Prompt#’, ‘#Rewritten Prompt#’, ‘given prompt’ and ‘rewritten prompt’ are not allowed to appear in #Rewritten Prompt#
    #Given Prompt#:
    {Here is instruction.} #Rewritten Prompt#:

    我希望你扮演一个提示词重写器(Prompt Rewriter)。
    你的目标是将给定的提示词(prompt)改写成更复杂的版本,以使那些著名的人工智能系统(例如 ChatGPT 和 GPT4)更难处理。但改写后的提示词必须是合理的,且必须能被人类理解并回应。
    你的改写不能省略 #给定提示词#(#Given Prompt#)中的非文本部分,例如表格和代码。此外,请不要省略 #给定提示词# 中的输入部分。
    你应当通过以下方法来使给定提示词复杂化:
    如果 #给定提示词# 包含对某些问题的询问,可以增加询问的深度和广度。
    你应尽力避免使 #改写后的提示词#(#Rewritten Prompt#)变得冗长,#改写后的提示词# 只能在 #给定提示词# 的基础上增加 10 到 20 个词。禁止在 #改写后的提示词# 中出现“#给定提示词#”、“#改写后的提示词#”、“given prompt”或“rewritten prompt”这些短语。
    **#给定提示词#:**
    {这里是指令。}
    **#改写后的提示词#:**

附录 B: Concretizing Prompt(具体化 Prompt)

  • 示例 B.1:用于深度演化的具体化提示 (Prompt for Concretizing of In-Depth Evolving)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    I want you act as a Prompt Rewriter.
    Your objective is to rewrite a given prompt into a more complex version to make those famous AI systems (e.g., ChatGPT and GPT4) a bit harder to handle. But the rewritten prompt must be reasonable and must be understood and responded by humans.
    Your rewriting cannot omit the non-text parts such as the table and code in #Given Prompt#:. Also, please do not omit the input in #Given Prompt#.
    You SHOULD complicate the given prompt using the following method:
    Please replace general concepts with more specific concepts.
    You should try your best not to make the #Rewritten Prompt# become verbose, #Rewritten Prompt# can only add 10 to 20 words into #Given Prompt#. ‘#Given Prompt#’, ‘#Rewritten Prompt#’, ‘given prompt’ and ‘rewritten prompt’ are not allowed to appear in #Rewritten Prompt#
    #Given Prompt#:
    {Here is instruction.} #Rewritten Prompt#:

    我希望你扮演一个提示词重写器(Prompt Rewriter)。
    你的目标是将给定的提示词改写成更复杂的版本,以使那些著名的人工智能系统(例如 ChatGPT 和 GPT4)更难处理。但改写后的提示词必须是合理的,且必须能被人类理解并回应。
    你的改写不能省略 #给定提示词# 中的非文本部分,例如表格和代码。此外,请不要省略 #给定提示词# 中的输入部分。
    你应当通过以下方法来使给定提示词复杂化:
    请将一般性概念替换为更具体的概念。
    你应尽力避免使 #改写后的提示词# 变得冗长,#改写后的提示词# 只能在 #给定提示词# 的基础上增加 10 到 20 个词。禁止在 #改写后的提示词# 中出现“#给定提示词#”、“#改写后的提示词#”、“given prompt”或“rewritten prompt”这些短语。
    **#给定提示词#:**
    {这里是指令。}
    **#改写后的提示词#:**

附录 C:Increased Reasoning Steps Prompt

  • 示例 C.1:用于深度演化的增加推理步骤提示 (Prompt for Increased Reasoning Steps of In-Depth Evolving)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    I want you act as a Prompt Rewriter.
    Your objective is to rewrite a given prompt into a more complex version to make those famous AI systems (e.g., ChatGPT and GPT4) a bit harder to handle. But the rewritten prompt must bereasonable and must be understood and responded by humans.
    Your rewriting cannot omit the non-text parts such as the table and code in #Given Prompt#:. Also, please do not omit the input in #Given Prompt#.
    You SHOULD complicate the given prompt using the following method:
    If #Given Prompt# can be solved with just a few simple thinking processes, you can rewrite it to explicitly request multiple-step reasoning.
    You should try your best not to make the #Rewritten Prompt# become verbose, #Rewritten Prompt# can only add 10 to 20 words into #Given Prompt#. ‘#Given Prompt#’, ‘#Rewritten Prompt#’, ‘given prompt’ and ‘rewritten prompt’ are not allowed to appear in #Rewritten Prompt#
    #Given Prompt#:
    {Here is instruction.} #Rewritten Prompt#:

    我希望你扮演一个提示词重写器(Prompt Rewriter)。
    你的目标是将给定的提示词改写成更复杂的版本,以使那些著名的人工智能系统(例如 ChatGPT 和 GPT4)更难处理。但改写后的提示词必须是合理的,且必须能被人类理解并回应。
    你的改写不能省略 #给定提示词# 中的非文本部分,例如表格和代码。此外,请不要省略 #给定提示词# 中的输入部分。
    你应当通过以下方法来使给定提示词复杂化:
    如果 #给定提示词# 可以通过几个简单的思考过程解决,你可以将其改写成明确要求多步推理的形式。
    你应尽力避免使 #改写后的提示词# 变得冗长,#改写后的提示词# 只能在 #给定提示词# 的基础上增加 10 到 20 个词。禁止在 #改写后的提示词# 中出现“#给定提示词#”、“#改写后的提示词#”、“given prompt”或“rewritten prompt”这些短语。
    **#给定提示词#:**
    {这里是指令。}
    **#改写后的提示词#:**

附录 D:Complicate Input Prompt

  • 示例 D.1:用于演化的复杂化输入提示 (Prompt for Complicate Input of Evolving)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    我希望你扮演一个提示词重写器。你的目标是使用数据格式将给定的提示词改写成更复杂的版本,以使那些著名的人工智能系统(例如 chatgpt 和 GPT4)更难处理。但改写后的提示词必须是合理的,且必须能被人类理解并回应。  
    你必须在 [改写后的提示词] 中添加 [XML 数据] 格式的文本作为输入数据。

    **#给定提示词#:**
    我正在使用这段 php 代码来获取 xml 数据

    **#改写后的提示词#:** 我有这个 xml 文件,我想获取 xml 数据以自动填充 HTML 表格,代码可以运行,但会导致表格内容重复。

    以下是 xml 数据:

    <root>
    <stats>
    <item>
    <day>2017-11-01</day>
    <impressions>2192</impressions>
    <money>1.96790003</money>
    </item>
    <item>
    <day>2017-11-02</day>
    <impressions>2824</impressions>
    <money>3.208500033</money>
    </item>
    <item>
    <day>2017-11-03</day>
    <impressions>3680</impressions>
    <money>3.321799981</money>
    </item>
    </stats>
    <total>
    <impressions>8696</impressions>
    <money>8.498200044</money>
    </total>
    <filter>
    <dateFrom>2017-11-01</dateFrom>
    <dateTo>2017-11-03</dateTo>
    <groupBy>day</groupBy>
    <format>xml</format>
    </filter>
    </root>

    我正在使用这段 php 代码来获取 xml 数据,但这段代码是从整个 xml 数据中获取,导致表格字段重复。

    <?php
    \$dom = new DOMDocument;
    \$dom -> load('http://example.com/', \$dateselected . '&dateTo =', \$dateselected2 . '&format=xml');
    \$day = \$dom->getElementsByTagName('day');
    \\$impressions = \$dom->getElementsByTagName('impressions');
    echo ( "<table>");
    foreach(\$day as \$node1) {
    foreach(\$impressions as \$node2) {
    echo '<tr>';
    echo "<td>", \$node1 -> textContent . "<td>";
    echo "<td>", \$node2 -> textContent . "<td>";
    echo "<td>", \$node2 -> textContent *0.5/1000 . "<td>";
    echo '</tr>';
    }
    }
    echo( "<table>");
    ?>

    有人能提示我如何修复这个问题吗?谢谢

    ####
  • 示例 D.2:用于演化的复杂化输入提示 (Prompt for Complicate Input of Evolving)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    我希望你扮演一个提示词重写器。你的目标是使用数据格式将给定的提示词改写成更复杂的版本,以使那些著名的人工智能系统(例如 chatgpt 和 GPT4)更难处理。但改写后的提示词必须是合理的,且必须能被人类理解并回应。  

    你必须在 [改写后的提示词] 中添加 [SQL 数据库] 格式的文本作为输入数据。

    **#给定提示词#**
    实现 SQL 查询结果

    **#改写后的提示词#**(必须包含一个具体的 SQL 数据库作为输入):
    有一个名为 messages 的表格,包含的数据如下所示:

    | Id | Name | Other_Columns |
    |----|------|---------------|
    | 1 | A | A_data_1 |
    | 2 | A | A_data_2 |
    | 3 | A | A_data_3 |
    | 4 | B | B_data_1 |
    | 5 | B | B_data_2 |
    | 6 | C | C_data_1 |

    如果我运行查询 `select * from messages group by name`,我将得到以下结果:

    | 1 | A | A_data_1 |
    | 4 | B | B_data_1 |
    | 6 | C | C_data_1 |

    哪个查询会返回以下结果?

    | 3 | A | A_data_3 |
    | 5 | B | B_data_2 |
    | 6 | C | C_data_1 |

    也就是说,应返回每个组中的最后一条记录。目前,我使用的查询是:

    SELECT *
    FROM (SELECT *
    FROM messages
    ORDER BY id DESC) AS x
    GROUP BY name

    但这看起来非常低效。是否有其他方法可以实现相同的结果?

    ####
  • 示例 D.3:用于演化的复杂化输入提示 (Prompt for Complicate Input of Evolving)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    我希望你扮演一个提示词重写器。你的目标是使用数据格式将给定的提示词改写成更复杂的版本,以使那些著名的人工智能系统(例如 chatgpt 和 GPT4)更难处理。但改写后的提示词必须是合理的,且必须能被人类理解并回应。  

    你必须在 [改写后的提示词] 中添加 [python 代码] 格式的文本作为输入数据。

    **#给定提示词#**
    转换 python 代码

    **#改写后的提示词#**(必须包含一个具体的 python 代码作为输入):
    我有以下 Python 代码:

    ```python
    cursor.execute("INSERT INTO table VALUES var1, var2, var3,")

    其中 var1 是整数,var2 和 var3 是字符串。
    如何编写变量名而不让 Python 将它们作为查询文本的一部分?

    ####

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    * **示例 D.4:用于演化的复杂化输入提示 (Prompt for Complicate Input of Evolving)**  
    ```md
    我希望你扮演一个提示词重写器。你的目标是使用数据格式将给定的提示词改写成更复杂的版本,以使那些著名的人工智能系统(例如 chatgpt 和 GPT4)更难处理。但改写后的提示词必须是合理的,且必须能被人类理解并回应。
    你必须在 [改写后的提示词] 中添加 [HTML 页面] 格式的文本作为输入数据。

    **#给定提示词#**
    滚动整个 HTML 页面

    **#改写后的提示词#**(必须包含一个具体的 HTML 页面作为输入):
    我希望能够滚动整个页面,但不显示滚动条。
    在 Google Chrome 中,可以使用:


    ::-webkit-scrollbar {
    display: none;
    }

    但 Mozilla Firefox 和 Internet Explorer 似乎不支持这种方式。
    我也在 CSS 中尝试了:

    overflow: hidden;

    这样可以隐藏滚动条,但我无法再滚动了。有没有办法可以在隐藏滚动条的同时仍然能够滚动整个页面?

    请仅使用 CSS 或 HTML。

    ###
  • 示例 D.5:用于演化的复杂化输入提示 (Prompt for Complicate Input of Evolving)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    我希望你扮演一个提示词重写器。你的目标是使用数据格式将给定的提示词改写成更复杂的版本,以使那些著名的人工智能系统(例如 chatgpt 和 GPT4)更难处理。但改写后的提示词必须是合理的,且必须能被人类理解并回应。  

    你必须在 [改写后的提示词] 中添加 [Shell 命令] 格式的文本作为输入数据。

    **#给定提示词#**
    Shell scp 文件

    **#改写后的提示词#**(必须包含一个具体的 Shell 命令作为输入):
    我正在尝试从远程服务器 scp 一个文件到我的本地机器。只有端口 80 是可访问的。
    我尝试了:

    ```shell
    scp -p 80 username@www.myserver.com/root/file.txt .

    但出现了这个错误:cp: 80: No such file or directory
    如何在 scp 命令中指定端口号?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    * **示例 D.6:用于演化的复杂化输入提示 (Prompt for Complicate Input of Evolving)**  
    ```md
    我希望你扮演一个提示词重写器。你的目标是使用数据格式将给定的提示词改写成更复杂的版本,以使那些著名的人工智能系统(例如 chatgpt 和 GPT4)更难处理。但改写后的提示词必须是合理的,且必须能被人类理解并回应。

    你必须在 [改写后的提示词] 中添加 [JSON 数据] 格式的数据作为输入数据,添加 [JSON 数据] 代码作为输入代码。

    改写后的提示词必须是一个问题式指令。

    **#给定提示词#:**
    给定一个客户购买历史的 JSON 数据集,我们如何计算客户在同一商店进行重复购买的概率?我们能否利用条件概率公式:\(P(A|B)=P(A\cap B)/P(B)\),其中 A 表示客户进行重复购买的事件,B 表示客户再次在同一商店购买的事件?此外,我们如何应用这个公式来识别最有可能进行重复购买的客户群体?你能提供一个使用给定 JSON 数据集实现这个公式的示例吗?

    改写后的提示词必须是一个问题式指令。

    **#改写后的提示词#**(必须包含一个具体的 JSON 数据作为输入):

附录 E:Difficulty Judge Prompt

  • 示例 E.1:用于判断指令难度的提示 (Prompt for Juding the Difficulty of Instructions)
    1
    2
    3
    4
    5
    6
    我们希望您评估并评定以下问题的难度和复杂性。您应给出一个从 1 到 10 的整体分数,分数越高表示难度和复杂性越高。您必须仅给出分数,不提供任何其他理由。  

    **## 问题:**
    { 这里是指令。 }

    **## 分数:**

附录 F:Equal Prompt

  • 示例 F.1:用于判断两个指令是否等价的提示 (Prompt for Determining whether Two Instructions are Equal)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    以下是两个给 ChatGPT AI 的指令,您认为它们是否彼此等价,需满足以下要求:  

    1. 它们具有相同的约束和要求。
    2. 它们具有相同的询问深度和广度。

    第一个提示:{这里是第一个指令。}

    第二个提示:{这里是第二个指令。}

    您的判断(仅回答:等价 或 不等价。无需解释原因。):

附录 G:Math Judgement Prompt

  • 示例 G.1:用于判断指令是否与数学相关的提示 (Prompt for judging whether an instruction is math related)
    1
    2
    3
    请判断以下问题是否是一个数学问题,并仅返回 True 或 False,不提供任何解释。  

    问题:{指令}

附录 H:WizardEval Analysis

  • 论文收集了 Evol-Instruct 测试集,其中包含来自各种来源的真实世界人类指令,例如在线开源项目、平台和论坛
  • 论文分析了数据并识别出 29 种不同的技能,这些技能代表了人类的主要需求,例如代码生成与调试、数学、推理、复杂格式、写作、广泛学科等等
  • 图 6 展示了论文测试集中实例和技能的分布情况
  • 论文的测试集包含 218 个实例,每个实例都是针对特定技能的指令
  • 论文将论文的测试集与 Vicuna 的测试集进行了比较,后者是用于评估指令遵循模型的基准数据集
  • 论文发现 Vicuna 的测试集只有 80 个实例和 9 种技能,比论文的测试集小得多且多样性低得多
  • 图 4a 显示了测试数据的难度和复杂性如何在不同实例间变化
  • 论文的测试数据具有更均匀的分布,这意味着它包含不同难度和复杂性级别的指令
  • 另一方面,Vicuna 和 Alpaca 的分布则存在偏差,这意味着它们主要包含低难度和低复杂性的指令
  • 这表明这两个语料库无法处理对更复杂和要求更高场景的评估

附录 I:Different difficulty Annotators

  • 论文仅使用 ChatGPT 来事后分析生成指令的“难度”分布,但论文并未使用此分析结果来指导数据生成或模型训练
  • 为了探索 ChatGPT 执行难度分析的能力,论文采样了 600 条指令,并使用更强大的 GPT-4 模型和 5 位受过良好教育的人类标注者一起进行难度评估
  • 评估结果见表 3。结果表明,ChatGPT、GPT-4 和人工标注在难度变化趋势上表现出高度的一致性
  • 为了研究 ChatGPT 难度评分的正确性,论文增加了一个新的实验来测量 ChatGPT 与人类之间在难度判断上的一致性:
    • 论文每次以相等概率从六个数据集(Alpaca、ShareGPT、C1 到 C4)中随机选择两条指令,组成一对
    • 总共论文选择了 300 个指令对
    • 然后,论文请 ChatGPT 和 5 位受过良好教育的人类标注者判断在一个指令对中哪一条更难,人类之间的 Kappa 分数为 0.68,ChatGPT 与人类(多数投票)之间的 Kappa 分数为 0.66,这表明 ChatGPT 和人类标注者之间具有良好的一致性

附录 J: Cluster Scatter Plot(聚类散点图)

  • 广度演化旨在增强主题覆盖度、技能覆盖度和整体数据集的多样性。为了(定性分析)检查不同数据集的广度(多样性),论文首先使用 BERT
  • 对每条指令进行编码并获得其 768 维的嵌入向量,然后使用名为 t-SNE 的降维算法将嵌入维度降至 2 维,最后论文应用聚类算法 k-means 将每个数据集的指令划分为 20 个簇,以便进行直观的可视化
  • 如图 7 所示,论文数据集的数据点比 ShareGPT 和 Alpaca(Self-Instruct)的数据点更加分散,这表明论文的指令具有更好的主题多样性

附录 K: Human Evaluation Aspects

  • 标注者从以下五个维度判断哪个回答更好:
    • (1) 相关性 (Relevance): 评估模型正确理解上下文和问题语义含义的能力
    • (2) 知识性 (Knowledgeable): 模型是否能够准确使用各种详细的知识来解决问题
    • (3) 推理能力 (Reasoning): 评估模型执行正确推理过程或设计有效推理概念以解决问题的能力
    • (4) 计算能力 (Calculation): 评估模型是否能在数学、生物、化学和物理领域对所提供的公式进行准确的数学计算
    • (5) 准确性 (Accuracy): 评估模型对于给定指令是否能在相应领域正确执行

附录 L: Performance details of different checkpoints

  • 在论文中,论文使用 3 个训练周期 (epoch) 训练论文的模型,并且在上文的“第 4 节 实验”中仅报告了最终检查点的性能,以与之前的工作保持一致
  • 如下表 4 所示,论文报告了模型在不同周期(2.5, 2.75, 3)的检查点性能
    • 对于 13B 模型,我们可以看到除了 GSM8k 之外,在每个基准测试上表现最好的始终是 WizardLM-13b (ShareGPT Seed)
    • 对于 65b/70b 模型,论文也看到 WizardLM-70b 在所有基准测试中都是最好的
    • 因此,作者认为这主要是由模型训练过程中在某些基准测试上的波动引起的
1…151617…65
Joe Zhou

Joe Zhou

Stay Hungry. Stay Foolish.

641 posts
53 tags
GitHub E-Mail
© 2026 Joe Zhou
Powered by Hexo
|
Theme — NexT.Gemini v5.1.4