大语言模型微调 llm sft ,llamafactory 启动参数详解,以医药信息作为案例

完整日志逐段拆解 + 报错/警告/关键参数深度讲解

环境:ROCm AMD GPU + LlamaFactory LoRA微调 Qwen2-5120(48层大模型),断点续训 checkpoint-2500,单卡训练。

一、前置脚本报错与优化方案

rocm-smi --gpureset
# ERROR: No device specified. One device must be specified for GPU reset

原因

--gpureset 必须指定单张GPU序号,不能批量重置所有卡;无参数会直接报错。

修复脚本(兼容单/多AMD卡)

export ACCELERATE_DEBUG=1
# 批量杀死训练进程(修复pkill警告)
pkill -9 -f python
pkill -9 -f torchrun
pkill -9 -f llamafactory-cli
pkill -9 -f launcher.py

# 自动获取所有GPU并逐个重置
GPUS=$(rocm-smi --showgpuinfo | grep GPU | awk '{print $2}')
for gpu in $GPUS; do
    rocm-smi -d $gpu --gpureset
done

llamafactory-cli train /workspace/training_configs_512/binding_paired.yaml

pkill 警告:pattern longer than 15 characters will match zero

  • Linux pkill 不加 -f 仅匹配进程名(限制15字符),llamafactory-cli等长命令会匹配失败;
  • 你已经加了 pkill -9 -f "llamafactory",这条警告可以忽略,属于无害提示。

二、Deprecated 日志:logging_dir 弃用提示

`logging_dir` is deprecated and will be removed in v5.2. Please set `TENSORBOARD_LOGGING_DIR` instead.
  • transformers 5.2版本废弃旧参数 logging_dir
  • 修复yaml配置:把 logging_dir: xxx 替换为 tensorboard_logging_dir: xxx

三、分布式训练基础信息

Process rank: 0, world size: 1, device: cuda:0, distributed training: False, compute dtype: torch.bfloat16
  • world_size=1单卡训练,无多卡DDP/DeepSpeed;
  • cuda:0:ROCm环境PyTorch依然复用cuda设备标识,底层是AMD HIP;
  • compute dtype=bfloat16:计算精度bf16,适合大模型训练,显存占用比fp16更低、数值稳定性更强。

四、Qwen2 模型配置解析(48层大基座)

"hidden_size": 5120,          # 模型维度 5120(超大尺寸,显存压力极高)
"num_hidden_layers": 48,     # 48层Transformer
"num_attention_heads": 40,
"num_key_value_heads": 8,    # GQA分组注意力,KV头远少于Q头,省显存
"max_position_embeddings": 131072, # 128k上下文窗口
"rope_theta": 1000000.0,     # 百万级RoPE缩放,适配超长文本
"vocab_size": 203711,
"tie_word_embeddings": false # 输入输出embedding不共享权重

重复加载config日志(连续三次load config.json)

无害,LlamaFactory内部流程:

  1. 读取模型基础配置
  2. 初始化分词器对齐token id
  3. 加载generation生成配置
    三次加载是正常流程,不影响性能。

五、数据集加载逻辑(AIGC蛋白→SMILES药物分子配对任务)

样本结构

  • Instruction:aigc drug + 蛋白氨基酸序列 <P>xxx</P>
  • Response:药物SMILES结构式 <L>xxx</L><|end_of_sentence|>

label_ids 全 -100 原理(LLaMA Factory标准微调逻辑)

  • -100 在CrossEntropyLoss中会自动忽略计算loss
  • 输入prompt部分(Instruction+蛋白序列)全部标记-100,只对Response(SMILES结构式)计算损失;
  • 完全符合SFT监督微调范式,日志里label/input_ids映射正常,数据集加载无错误。

六、关键警告1:FlashAttention-2 is not installed

[WARNING] FlashAttention-2 is not installed.

影响

  • 未启用FlashAttention,使用原生SDPA注意力,显存占用更高、速度更慢
  • AMD ROCm环境FlashAttention适配差,官方FlashAttention对HIP支持残缺,不用强行安装,下文AOTriton SDPA是AMD最优替代。

替代方案(你当前已生效)

日志后续:Using torch SDPA for faster training,PyTorch原生缩放点积注意力,ROCm下AOTriton后端加速。

七、ROCm HIP 内存警告:expandable_segments not supported

UserWarning: expandable_segments not supported on this platform (Triggered internally at /pytorch/c10/hip/HIPAllocatorConfig.h:36.)

原理

PyTorch CUDA有可扩展内存分段分配(预分配大块显存动态扩容,减少cudaMalloc调用);
AMD HIP架构不支持该机制,只能按需小块申请显存。

影响与优化

  1. 无害警告,不报错崩溃,仅分配效率轻微下降;
  2. 缓解:设置HIP预留显存环境变量,减少频繁分配:
export PYTORCH_HIP_ALLOC_CONF=max_split_size_mb:2048
export HIP_VISIBLE_DEVICES=0

八、模型加载核心信息

  1. 权重加载safetensors 安全权重格式,100%加载完成,无权重缺失/损坏;
  2. 精度策略:基座模型加载为 bfloat16,LoRA微调参数自动upcast到float32(日志:Upcasting trainable params to float32
    • 逻辑:基座冻结bf16省显存,LoRA权重fp32保证梯度更新精度,标准LoRA优化方案;
  3. 微调方式:Fine-tuning method: LoRA
    • 参数统计:
      trainable params: 275,251,200 || all params: 15,574,150,144 || trainable%: 1.7674
      
      总参155亿,可训练LoRA仅2.75亿,占比1.77%,显存压力可控;
  4. 梯度检查点开启:Gradient checkpointing enabled
    • 牺牲少量计算速度,大幅降低激活值显存占用,5120维度大模型必须开启,否则OOM;
  5. KV Cache训练关闭:KV cache is disabled during training
    • 训练阶段不需要缓存KV,推理才启用,正常行为。

九、Token ID 对齐警告(重要配置点)

The tokenizer has new PAD/BOS/EOS tokens that differ from the model config and generation config.
Updated tokens: {'eos_token_id': 203704, 'bos_token_id': 203703, 'pad_token_id': 203704}

原因

基座原始Qwen2 config中pad_token_id=null,你自定义分词器新增了特殊token(<|end_of_sentence|>对应203704);
框架自动覆盖模型/生成配置的token id,保证训练、推理token一致性。

风险提示

训练没问题,但导出推理模型前需要保存更新后的config/generation_config,否则推理时token id不匹配会乱生成。

十、断点续训核心参数(训练任务全貌)

Num examples = 209,776      # 总训练样本20.9万
Num Epochs = 3              # 完整训练轮次3轮
Instantaneous batch size per device = 1  # 单卡微批次1
Gradient Accumulation steps = 16         # 梯度累积16步
Total train batch size = 1*16=16         # 等效批次16
Total optimization steps = 39,333        # 总迭代步数
Resume from global step 2500, epoch 0

计算逻辑

总步数公式:ceil(总样本 / 等效批次) * 轮次 = ceil(209776/16)*3 = 39333,参数匹配无误;
当前从第2500步继续训练,会自动跳过前2500个梯度累积批次,数据加载断点逻辑正常。

十一、AOTriton SDPA 前后向警告(最末尾两行核心讲解)

UserWarning: Using AOTriton backend for Efficient Attention forward...
UserWarning: Using AOTriton backend for Efficient Attention backward..

1. AOTriton 是什么

Triton是PyTorch官方GPU内核编程语言,AOT = Ahead-of-Time 预编译
ROCm AMD平台没有FlashAttention,PyTorch针对HIP开发了AOTriton实现的SDPA(缩放点积注意力),是AMD显卡目前速度最优的注意力内核。

2. 警告含义

不是报错,是信息提示:前向、反向传播全部启用预编译Triton注意力算子,替代原生HIP实现。

优缺点

✅ 优势

  1. AMD ROCm唯一稳定高效注意力实现,比原生HIP SDPA提速20~40%;
  2. 兼容bfloat16、GQA注意力(你的Qwen2 GQA完美适配);
  3. 和梯度检查点、LoRA微调无冲突。
    ❌ 劣势
  4. 第一次运行会触发内核编译,前几百步训练速度偏慢,编译缓存后速度稳定;
  5. 相比N卡FlashAttention显存占用略高;
  6. 极低版本ROCm可能出现数值误差,建议ROCm 5.7+。

优化手段(进一步提速)

# 开启Triton缓存,避免每次重启重新编译
export TRITON_CACHE_DIR=/workspace/triton_cache
# 启用ROCm优化编译器
export ROCM_USE_FLASH_ATTN_V2_TRITON=1

十二、整体状态总结

  1. 无致命错误,训练已正常启动,进度条 0/39333 代表训练正在运行;
  2. 所有日志均为警告/弃用提示/信息输出,不存在OOM、算子报错、权重加载失败、数据集报错;
  3. 环境适配:AMD ROCm + AOTriton注意力 + 梯度检查点 + LoRA微调 组合合理;
  4. 待优化点(可选,提升稳定性/速度):
    • 修复 rocm-smi --gpureset 批量重置脚本;
    • yaml替换废弃 logging_dir 参数;
    • 配置HIP显存分配、Triton缓存环境变量;
    • 训练结束导出模型时保存更新后的token config,防止推理异常。

label_ids、labels 完整拆解,一句话先讲核心:

1. label_ids 数组含义

规则基础

PyTorch 训练大模型时,交叉熵损失函数 CrossEntropyLoss 规定:值为 -100 的 token 直接忽略,不计算损失、不参与梯度更新

分段对应你的样本

  1. 前面超长一串全部 -100
    对应 input_ids 里整段 Prompt:
Below is an instruction...
### Instruction:
aigc drug
<P>长蛋白氨基酸序列</P>
### Response:

这一整段是输入提示词(上下文),我们不希望模型学习“复述蛋白、复述指令”,所以全部标 -100,训练时不在这里算 loss。

  1. 末尾正常数字:203706,46,28…203704
    这部分才是模型需要预测输出的目标答案
    <L>SMILES分子串<|end_of_sentence|>
    只有这段会计算损失,反向传播更新 LoRA/模型权重。
  • 203706 = 自定义标记 <L> 的token id
  • 中间一堆数字 = SMILES结构式逐字符分词ID
  • 203704 = 结束符 <|end_of_sentence|>,代表分子生成完毕

这么设计的好处(贴合你的药物生成任务)

只约束模型学会:读蛋白序列 → 输出对应药物SMILES,不会乱学复述输入蛋白、冗余指令,完全是标准SFT监督微调掩码方案。

2. 下方 labels: 文本行

<L>O=C(c1ccc(cc1)S(=O)(=O)N)Cn1cnc2c1cccc2</L><|end_of_sentence|>
  • 纯日志打印用,方便你肉眼调试,不参与任何训练计算
  • 和 label_ids 末尾那串数字一一对应:数字ID还原出来就是这段分子文本;
  • <L> = 分子开头标记,<|end_of_sentence|> = 生成终止标记,是你自定义新增的特殊分词。

3. 补充关键细节

  1. 为什么不是全部token都参与loss?
    如果不掩码、不填-100,模型会被迫学习“预测下一个氨基酸、预测指令文字”,任务跑偏,收敛极慢、效果变差。
  2. 和 input_ids 的关系
  • input_ids:完整整段(指令+蛋白+分子),给模型做输入;
  • label_ids:相同长度,输入部分屏蔽(-100),仅分子部分保留真实token作为学习目标。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值