基于Qwen2.5技术报告的一些思考
Qwen2.5-Coder 继承了 Qwen2.5 的词汇表,但引入了几个特殊标记来帮助模型更好地理解代码。标记文本或序列的结尾,而和标记用于实现中间填充 (FIM) 技术(Bavarian 等人,2022),其中模型预测代码块的缺失部分。此外,用于在 FIM 操作期间进行填充。其他标记包括,用于标识存储库名称,以及,用作文件分隔符以更好地管理存储库级信息。这些标记对于帮助模型从不同的代码结构中学
基于Qwen2.5技术报告的一些思考
1. 技术概要
1.1 引入特殊标记
Qwen2.5-Coder 继承了 Qwen2.5 的词汇表,但引入了几个特殊标记来帮助模型更好地理解代码。
标记文本或序列的结尾,而 <|fim_prefix|>
、<|fim_middle|>
和 <|fim_suffix|>
标记用于实现中间填充 (FIM) 技术(Bavarian 等人,2022),其中模型预测代码块的缺失部分。此外,<|fim_pad|>
用于在 FIM 操作期间进行填充。其他标记包括 <|repo_name|>
,用于标识存储库名称,以及 <|file_sep|>
,用作文件分隔符以更好地管理存储库级信息。
这些标记对于帮助模型从不同的代码结构中学习至关重要,并使其能够在文件级和存储库级预训练期间处理更长、更复杂的上下文。
1.2 训练数据
数据类型
论文特别强调了构建高质量、广泛多样的代码预训练数据集:
- 源代码数据:从 GitHub 的公共库中获取,涵盖 92 种编程语言,数据清洗严格以确保高质量。
- 文本-代码混合数据:从大规模网络抓取数据中筛选出与代码相关的文档、教程和博客,采用层次化筛选技术来提升数据质量。
- 合成数据:利用前代模型 CodeQwen1.5 生成大规模的代码合成数据,并通过执行器验证代码是否可执行。
- 数学数据:包含 Qwen2.5-Math 的数学训练数据,用于提升模型的数学推理能力。
- 文本数据:包含普通自然语言数据,用于保持模型在非代码任务中的通用能力。
数据比例
预训练时,论文特别设计了 代码:文本:数学 的数据混合比例,最终确定 70% 代码、20% 文本和 10% 数学数据的组合,使模型不仅在代码生成任务上表现优异,在通用自然语言处理任务和数学推理上也有较好的表现。一种可能的解释是,数学和文本数据可能会对代码性能产生积极贡献。
最终的训练数据集包含 5.2 万亿个令牌。
1.3 三阶段训练
文件级预训练
文件级预训练的目的是让模型从独立的代码文件中学习基本的代码模式、语法结构以及上下文信息。这一阶段的训练帮助模型在局部代码结构和上下文理解上打下坚实的基础。
- 数据:使用超过 5.2 万亿 tokens 的高质量代码数据,来自多个源代码库和数据源。数据经过了严格的清洗与筛选,确保模型学习到的是规范的、有效的代码。
- 训练细节:
-
最大序列长度:设置为 8192 tokens,能够覆盖较大的代码片段。
-
训练任务:
- 下一个 token 预测:即经典的自回归训练方法,预测序列中的下一个 token。
- 填补中间(Fill-in-the-Middle, FIM):这是代码特定的任务,模型不仅要预测下一个 token,还要在给定代码的前后部分的基础上补全中间缺失的代码。
FIM 的格式如下:
code_pre 是代码的前缀部分, code_suf 是代码的后缀部分, code_mid 是模型需要预测和生成的中间部分。
这种任务设计可以帮助模型学会在完整的代码上下文中补全部分代码,提升其代码补全和生成的能力。
-
repo 级预训练
repo 级预训练,旨在增强模型的长上下文能力。在此阶段,上下文长度从 8192 个 token 扩展到 32768 个 token。
- 数据:使用了约 3000 亿 tokens 的高质量、长代码数据,这些数据通常来自多个文件的代码库,具有较强的跨文件关联性和上下文依赖性。
- 训练细节:
- 最大序列长度:序列长度从 8192 tokens 扩展到 32768 tokens,使模型能够处理更长的上下文。
- RoPE(旋转位置编码):为了处理超长序列,位置编码的基准频率从 10000 调整为 1000000,从而增强了模型对长上下文的感知能力。
- YARN 机制:采用了 YARN(Yet Another RoPE Network)机制,使模型能够进一步外推到长达 131072 tokens(即 132K tokens)的序列长度。这种机制扩展了模型的记忆能力,使其能够处理跨多个文件和复杂项目结构的代码任务。
- FIM 任务扩展:将文件级 FIM 任务扩展到了仓库级别的代码生成和补全。例如,在处理项目仓库时,模型的输入格式为:
SFT后训练
指令微调的目的是将模型从通用代码生成转化为代码助手和编码代理,以更好地适应实际的编程任务和应用场景。
-
数据:指令微调使用了经过精心设计和处理的大规模指令数据集,包括来自真实世界应用的问题和解决方案,以及生成的合成数据。具体包括以下几类数据:
- 来自 GitHub 等代码平台的真实代码片段和相应的指令。
- LLM(大语言模型)生成的指令和代码对,这些生成数据经过模型评分器的筛选,以确保数据质量。
- 多语言编程数据,为模型提供多编程语言的指令样本,增强其跨语言的通用性。
-
训练细节:
- 多阶段微调:指令微调采用粗到细的两阶段策略:
- 第一阶段:使用数千万条质量较低但多样性较高的指令样本对基础模型进行微调。
- 第二阶段:采用高质量指令样本进行精细微调,通过拒绝采样(Rejection Sampling)和监督微调(Supervised Fine-Tuning)提升模型性能。对于同一个查询,模型会生成多个候选答案,然后由模型评分器挑选出最优答案用于微调。
- 混合微调:考虑到大多数指令数据长度较短,团队通过 FIM 格式 构建长上下文指令对,以保留模型处理长上下文的能力。核心目的是在提升模型短指令任务能力的同时,确保其对长上下文的处理能力不被削弱。例如,模型会基于代码的抽象语法树(AST)提取代码逻辑块进行填充,从而进一步提升其代码推理和生成能力。
- 多阶段微调:指令微调采用粗到细的两阶段策略:
2. openAI O1
传统的逐一教导任务方法不适用于大规模任务,反而通过激励结构,可以有效促进模型自发学习通用技能。虽然激励机制对人类而言可能需要更长时间,但对于机器可以通过增加计算资源即可加速学习。
他提出了类比“教人钓鱼”的方式,强调激励学习的重要性:“授人以鱼,不如授人以渔”,但是更进一步的激励应该是:“让他知道鱼的美味,并让他保持饥饿”,这样他就会主动去学习如何钓鱼。在这个过程中,他还会学会其他技能,如耐心、阅读天气、了解鱼类等。而其中有些技能是通用的,可以应用到其他任务中。
- 强调 o1 不是一个“系统”而是一个经过系统训练的模型。
- mini 在某些方面确实更好,只是世界知识不够多
- o1 模型即将支持更大的输入上下文
- o1 本身是有多模态能力的
- CoT token 不会被公开
- 提示可以影响模型思考问题方式
- 强化学习 (RL) 用于改善 o1 中的 CoT,GPT-4o 无法仅通过提示匹配其 CoT 性能
- 正在为模型添加广泛的世界知识
更多推荐
所有评论(0)