如何进行有监督微调(Supervised Fine-Tuning, SFT)

操作

chat template

先将数据调整成大模型固定的模板

这个模板一般记录在大模型的tokenizer配置文件里

调用相关的包就能使用这个模板

completions only

只关注回答结果是否符合预期就行,所以只要计算大模型结果的loss就行


提问那部分,不需要计算loss,就mask为0

NEFTune(noisy embeddings fintuning)

CV可以数据增强,文本也可以
在文本处理成token的embedding阶段,就加上噪声,

# NEFTune 超参数:控制噪声强度,通常取值在 5-15 之间
neftune_noise_alpha = 10

for i in range(epoch):
    # 确保模型处于训练模式
    model.train()
    
    for inputs, loss_mask in data_loader:
        # 1. 提取输入 ID,并从原 inputs 中移除,防止后续重复计算
        input_ids = inputs.pop("input_ids")
        
        # 2. 将 Token ID 转换为原始词向量 (Embedding)
        # 获取形状为 [batch_size, seq_len, hidden_dim] 的张量
        input_embeddings = model.base_model.model.model.embed_tokens(input_ids)
        
        # 3. 计算噪声缩放维度系数 (L * d)
        # size(1) 是序列长度 L,size(2) 是隐藏层维度 d
        dims = torch.tensor(input_embeddings.size(1) * input_embeddings.size(2))
        
        # 4. 计算噪声的最大幅值 (Magnitude)
        # 核心公式:alpha / sqrt(L * d)
        mag_norm = neftune_noise_alpha / torch.sqrt(dims)
        
        # 5. 生成并注入均匀分布噪声
        # 创建一个与嵌入向量形状相同的张量,填充 (-mag_norm, mag_norm) 之间的随机数
        # 这种抖动能增强模型对抗过拟合的能力,提高泛化性能
        noise = torch.zeros_like(input_embeddings).uniform_(-mag_norm, mag_norm)
        input_embeddings = input_embeddings + noise
        
        # 6. 将处理后的嵌入向量重新放入输入字典
        # 当模型接收到 inputs_embeds 时,会直接跳过自带的 Embedding 层进行前向传播
        inputs["inputs_embeds"] = input_embeddings
        
        # 7. 后续的标准前向传播与反向传播
        # outputs = model(**inputs)
        # ...
        
    # 每个 epoch 结束后,记得在验证/推理阶段关闭噪声
    # model.eval()

教程