大模型写代码早已不新鲜,但真要把代码能力调到生产可用,数据和自然语言微调很不一样。代码对上下文的要求苛刻,注释承担了大量语义,格式差一点就跑不起来。本文按机制层思路,讲清代码数据的几个特殊性和对应的处理讲究。
代码数据的三个特殊性
第一是强依赖上下文。一个函数的意义常常取决于同文件里的 import、类定义和工具函数,单独切出来模型只能瞎猜。第二是格式敏感。缩进、括号配对、引号风格错一点,代码直接报错,而自然语言里同样的错往往不影响阅读。第三是版本与时效。框架 API 更新快,三年前的示例代码可能是错的用法,语料要按版本筛。还有一点:不同语言的生态差异大,Python 的示例遍地都是,某些内部语言的优质样本极少,配比要按目标场景定,不能按网上数量定。
这些特殊性分别怎么处理,对照着看。
| 特殊性 | 具体表现 | 该怎么处理 |
|---|---|---|
| 强依赖上下文 | 函数意义取决于同文件的 import、类定义和工具函数 | 按函数、类、文件切,同文件依赖留在同一段 |
| 格式敏感 | 缩进、括号配对、引号风格错一点就报错 | 按代码结构切分,别按固定长度硬切 |
| 版本与时效 | 框架 API 更新快,三年前的示例可能是错的用法 | 语料按版本筛 |
| 语言生态差异 | Python 的示例遍地,某些内部语言优质样本极少 | 配比按目标场景定,不按网上数量定 |
保留完整文件上下文
对应的第一个讲究是切分方式。别按固定长度硬切,要按代码结构切:以函数、类、文件为单位,同文件的依赖尽量留在同一段里。仓库级数据还要保留目录结构和配置文件,让模型看到「谁调用谁」。进来的是一整个仓库,出去的是带结构信息的训练单元,而不是一堆无主片段。上下文长度是硬约束,长文件装不下时优先保留与目标函数直接相关的依赖,远处的工具函数可以截断,但要在样本里留标记说明有截断。
注释是语义桥梁
第二个讲究是注释。很多人觉得注释是噪音,其实恰恰相反:注释用自然语言解释了代码意图,是模型理解「这段为什么这么写」的主要线索。构造数据时保留 docstring 和行内注释,删注释反而丢信息。还可以反向构造「注释生成代码」和「代码生成注释」的配对任务,让模型学会两种方向的映射,这类样本在训练集里通常效果很好。反过来也要防一种情况:注释里混着过时说明,代码改了注释没改,这种样本会教坏模型,构造时要核对注释与代码是否一致。
任务形式与评估
第三个讲究是任务形式与评估。常见任务有补全、生成、改写、修错、解释,各自的数据形态不同,别混成一锅粥。评估也和自然语言差别很大:看编译通过率、单元测试通过率、静态检查告警数,比看「像不像好代码」客观得多,做法参考微调后的模型怎么评估里的测试集思路。补全任务的数据可以从现有仓库直接切,生成任务要人工设计需求描述,两类数据的配比影响模型行为偏向。
代码语料的来源可以来自内部仓库,整理方法和领域微调的数据从哪来是同一套流程;多语言覆盖不足时,用自我训练扩题型也常见。显存不够时的省法见微调的显存是怎么省的,卡不够时的档位现实见消费级显卡能微调多大模型。另外,代码任务的评估可以借力现成工具:让 DeepSeek 或通义千问对同一批测试题各出一版答案,和微调后的模型横向对比,差距一目了然。
- 特殊性:依赖上下文、格式敏感、版本时效,三条都绕不开
- 切分:按代码结构切,同文件依赖尽量留在一起
- 注释:是语义桥梁不是噪音,保留并做双向任务
- 任务:补全、生成、改写、修错、解释分开构造
- 评估:编译与测试通过率,比主观看好使得多
关于代码微调,问得最多的三个
- 只喂函数不喂整个文件行吗?:短函数可以,涉及复杂依赖时必须带上下文,否则模型学的是「猜」而不是「读」。
- 代码数据要按语言配比吗?:要,主流语言多给,长尾语言少给,完全不给某项语言,模型在该项上的生成质量会明显塌。
- 测试通过率是唯一标准吗?:不是,它不覆盖可读性和风格一致性,通常还要配人工抽检和静态检查一起看。


