主题
AMD 24G + 256G 工作站模型微调(炼丹)计划与实操手册
适用机器:AMD RX 7900 XTX 24G(RDNA3/gfx1100)+ 80 核 CPU + 256G 内存。 目标:把这张卡能炼的"丹"(各类型模型微调任务)讲清楚——什么能炼、怎么炼、炼完怎么部署。
生态基线(2026 中):ROCm 7.x + PyTorch ROCm 官方支持 gfx1100;LLaMA-Factory / Unsloth / PEFT 均可用; 训练速度约为同配置 RTX 4090 的 75~85%,完全可接受。
1. 炼丹能力总表(先定计划)
| 训练类型 | 推荐模型 | 方法 | 显存占用(估) | 可行性 |
|---|---|---|---|---|
| Embedding/分类模型微调 | BGE-small/large-zh(≤1.5B) | 全参数 | 4~10G | ✅ 轻松,最快上手 |
| SFT 指令微调 | Qwen3-0.6B / 1.7B | 全参数 | 8~20G | ✅ 适合理解全流程 |
| SFT 指令微调 | Qwen3-8B / Qwen3.5-9B | QLoRA(4bit) | 8~12G | ✅ 主力场景 |
| SFT 指令微调 | Qwen3-14B | QLoRA | 12~16G | ✅ 舒适 |
| SFT 指令微调 | Qwen3-32B | QLoRA | 19~22G | ⚠️ 极限:batch=1、seq≤1024、开梯度检查点 |
| DPO 偏好对齐 | 基于已 SFT 的 8B | QLoRA | 12~18G(双模型) | ✅ |
| 多模态 VLM 微调 | Qwen2.5-VL-3B / 7B | LoRA | 10~20G | ✅ 3B 轻松、7B 紧凑 |
| 领域继续预训练 | Qwen3-4B / 8B | LoRA | 10~18G | ✅ |
| 知识蒸馏 | 122B-A10B(生成)→ 8B(学习) | 推理造数据 + SFT | 走内存推理 | ✅ 发挥 256G 内存优势 |
| 全参数微调 ≥7B | — | — | >40G | ❌ 单卡 24G 不现实 |
性能预期:同等配置比 RTX 4090 慢 15~25%;QLoRA 8B / 1 万条数据 / 3 epoch 约 2~4 小时。
2. 炼丹路线图(建议顺序)
阶段1(半天) Embedding 微调 → 熟悉数据格式与训练流程,30 分钟见效
阶段2(1 天) Qwen3-0.6B 全参 SFT → 吃透 LLaMA-Factory 全流程
阶段3(持续) Qwen3-8B QLoRA SFT → 主力生产场景:业务知识库问答/客服/Agent
阶段4(进阶) DPO 对齐 / VLM / 14B → 按业务需要逐个解锁
阶段5(闭环) 合并 → GGUF 量化 → 部署 → 接《AMD 24G+256G MoE 部署指南》对外服务3. 环境搭建(一次性)
3.1 ROCm + PyTorch
bash
# 1) ROCm(已装可跳过;gfx1100 免 HSA_OVERRIDE 补丁)
sudo amdgpu-install --usecase=rocm,hip
sudo usermod -aG render,video $USER # 重新登录生效
rocminfo | grep gfx # 期望看到 gfx1100
# 2) Python 虚拟环境 + PyTorch ROCm 版
python3 -m venv ~/venvs/train && source ~/venvs/train/bin/activate
pip install torch torchvision --index-url https://download.pytorch.org/whl/rocm6.2
# 3) 验证(ROCm 下 torch.cuda 接口是正常用法)
python -c "import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))"
# 期望: True AMD Radeon RX 7900 XTX3.2 LLaMA-Factory(主力训练框架)
bash
pip install llamafactory[torch,metrics]
pip install bitsandbytes # QLoRA 需要(ROCm 版功能可用但非最优内核)
llamafactory-cli version3.3 关键环境变量(写入 ~/.bashrc 或训练脚本开头)
bash
export PYTORCH_ROCM_ARCH=gfx1100
# 显存碎片优化(ROCm 同样生效,长序列训练强烈建议)
export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True
# RDNA3 无官方 FlashAttention-2 → 统一用 SDPA(LLaMA-Factory 配置 flash_attn: disabled)4. 实操一:Embedding 模型微调(最快见效,30 分钟)
场景:让向量模型更懂你的业务术语,提升 RAG 检索命中率。
bash
pip install sentence-transformers datasetspython
# train_bge.py
from sentence_transformers import SentenceTransformer, InputExample, losses
from torch.utils.data import DataLoader
model = SentenceTransformer('/data/models/bge-small-zh-v1.5') # 换成你的本地路径
# 业务语料:(问题, 正确文档) 对,几百条即可见效
examples = [
InputExample(texts=['RKE2 加入节点报 x509 错误怎么办', 'tls-san 配置指南']),
InputExample(texts=['vLLM 启动 OOM 怎么调', 'gpu-memory-utilization 参数说明']),
# ... 几百~几千条
]
loader = DataLoader(examples, shuffle=True, batch_size=32)
loss = losses.MultipleNegativesRankingLoss(model)
model.fit(train_objectives=[(loader, loss)], epochs=3, warmup_steps=50,
output_path='/data/models/bge-small-zh-v1.5-ft')
print('完成,输出到 /data/models/bge-small-zh-v1.5-ft')bash
python train_bge.py # 24G 显存占用约 4~6G5. 实操二:Qwen3-0.6B 全参数 SFT(吃透全流程)
yaml
# qwen3-0.6b-full-sft.yaml
model_name_or_path: /data/models/Qwen3-0.6B
stage: sft
do_train: true
finetuning_type: full # 全参数微调
dataset: alpaca_zh_demo # 内置示例数据,先跑通;后续换业务数据
template: qwen3
cutoff_len: 2048
per_device_train_batch_size: 4
gradient_accumulation_steps: 4
learning_rate: 1.0e-5 # 全参微调 lr 要小
num_train_epochs: 3.0
bf16: true # RDNA3 支持 bf16
flash_attn: disabled # ROCm 用 SDPA
gradient_checkpointing: true
output_dir: saves/qwen3-0.6b-full-sft
logging_steps: 10
save_steps: 500bash
llamafactory-cli train qwen3-0.6b-full-sft.yaml6. 实操三:Qwen3-8B QLoRA SFT(主力场景)
yaml
# qwen3-8b-qlora-sft.yaml
model_name_or_path: /data/models/Qwen3-8B
stage: sft
do_train: true
finetuning_type: lora
lora_rank: 16
lora_alpha: 32
lora_dropout: 0.05
lora_target: all # 所有线性层都挂 LoRA
quantization_bit: 4 # QLoRA:基座 4bit 加载
dataset: your_business_data # 业务数据(alpaca 格式 json,见下)
template: qwen3
cutoff_len: 2048
per_device_train_batch_size: 2
gradient_accumulation_steps: 8 # 等效 batch = 16
learning_rate: 1.0e-4 # LoRA lr 比全参大一个量级
num_train_epochs: 3.0
bf16: true
flash_attn: disabled
gradient_checkpointing: true
optim: paged_adamw_8bit # 分页优化器再省显存
output_dir: saves/qwen3-8b-qlora-sft
logging_steps: 10
save_steps: 200
plot_loss: true业务数据格式(data/your_business_data.json,注册到 data/dataset_info.json):
json
[
{
"instruction": "RKE2 集群新节点 join 失败如何排查?",
"input": "",
"output": "按顺序排查:1) 9345 端口与防火墙……"
}
]bash
llamafactory-cli train qwen3-8b-qlora-sft.yaml
# 显存预期 8~12G;1 万条数据 3 epoch 约 2~4 小时7. 实操四:DPO 偏好对齐(让模型"更懂你偏好")
在 SFT 产物上继续做,数据为 (chosen, rejected) 对:
yaml
# qwen3-8b-dpo.yaml(在 §6 的 SFT LoRA 基础上)
model_name_or_path: /data/models/Qwen3-8B
adapter_name_or_path: saves/qwen3-8b-qlora-sft # 加载 SFT adapter
stage: dpo
do_train: true
finetuning_type: lora
lora_rank: 16
lora_target: all
quantization_bit: 4
dataset: your_preference_data # {"chosen": "...", "rejected": "..."} 格式
template: qwen3
cutoff_len: 2048
per_device_train_batch_size: 1
gradient_accumulation_steps: 8
learning_rate: 5.0e-6 # DPO lr 要更小
num_train_epochs: 1.0
pref_beta: 0.1
bf16: true
flash_attn: disabled
gradient_checkpointing: true
output_dir: saves/qwen3-8b-dpo8. 实操五:多模态 VLM 微调(Qwen2.5-VL-3B LoRA)
yaml
# qwen2p5-vl-3b-lora.yaml
model_name_or_path: /data/models/Qwen2.5-VL-3B-Instruct
stage: sft
do_train: true
finetuning_type: lora
lora_rank: 16
lora_target: all
dataset: your_vlm_data # 图文对数据
template: qwen2_vl
cutoff_len: 2048
per_device_train_batch_size: 1
gradient_accumulation_steps: 8
learning_rate: 1.0e-4
num_train_epochs: 3.0
bf16: true
flash_attn: disabled
gradient_checkpointing: true
output_dir: saves/qwen2p5-vl-3b-lora9. 实操六:领域继续预训练(注入行业知识)
yaml
# 与 SFT 区别仅三行:stage 换 pt、数据集为纯文本、lr 略降
stage: pt
dataset: your_domain_corpus # 纯文本领域语料(运维文档/PDF 转 txt)
learning_rate: 5.0e-5用法:先领域预训练(pt)→ 再指令微调(sft),两步串联效果最佳。 蒸馏玩法:用《MoE 部署指南》里的 122B-A10B 在内存中批量生成领域问答对 → 喂给本页 SFT。
10. 训练后闭环:合并 → GGUF → 部署
bash
# 1) LoRA 合并回基座(全参微调可跳过)
llamafactory-cli export \
--model_name_or_path /data/models/Qwen3-8B \
--adapter_name_or_path saves/qwen3-8b-qlora-sft \
--template qwen3 --finetuning_type lora \
--export_dir /data/models/Qwen3-8B-sft-merged --export_size 2 --export_legacy_format False
# 2) 转 GGUF + 量化(用之前编译的 llama.cpp)
python llama.cpp/convert_hf_to_gguf.py /data/models/Qwen3-8B-sft-merged \
--outfile /data/models/qwen3-8b-sft-f16.gguf
./llama.cpp/build/bin/llama-quantize \
/data/models/qwen3-8b-sft-f16.gguf /data/models/qwen3-8b-sft-Q4_K_M.gguf Q4_K_M
# 3) 部署(任选其一,详见《AMD 24G+256G MoE 部署指南》)
./llama.cpp/build/bin/llama-server -m /data/models/qwen3-8b-sft-Q4_K_M.gguf -ngl 99 -c 8192 --port 8080
# 或 Ollama:写 Modelfile(FROM ./qwen3-8b-sft-Q4_K_M.gguf)后 ollama create qwen3-8b-sft11. 训练中监控
bash
watch -n 2 rocm-smi # 显存/功耗/温度(训练时显存应贴近 90%+ 才算吃满)
nvtop # 更直观(支持 AMD)
tail -f saves/*/training_log.jsonl # loss 曲线(LLaMA-Factory 也会在终端滚动)12. 故障速查
| 现象 | 处理 |
|---|---|
torch.cuda.is_available() 返回 False | PyTorch 装错成 CPU 版,重装 rocm wheel;确认在 render/video 用户组 |
| 训练开始即 OOM | 先确认 expandable_segments:True;降 batch→1、开 gradient_checkpointing、缩 cutoff_len、上 quantization_bit: 4 |
| bitsandbytes 报错/找不到内核 | ROCm 版 bnb 兼容性一般:升级 bnb;或放弃 QLoRA 改纯 LoRA(bf16 基座,8B 约 18G 也可行) |
| loss = NaN | lr 过大(LoRA 超过 2e-4);确认 bf16: true 而非 fp16 溢出;数据中有异常超长样本 |
| 报 HIP/flash-attention 错误 | 确认 flash_attn: disabled;ROCm 需用 flash-attention-rocm 分支才能开 fa2 |
| 训练极慢 | rocm-smi 看是否跑在显卡上;数据集是否预处理(先 tokenize 缓存);80 核可加大 dataloader_num_workers |
| 合并导出 OOM(内存) | export 时加 --export_size 2(分片导出),256G 内存足够 |
13. 显存估算参考(梯度检查点开、seq 2048)
| 规模 | 全参数(bf16+Adam) | LoRA(bf16 基座) | QLoRA(4bit 基座) |
|---|---|---|---|
| 0.6B | ~8G ✅ | ~3G | ~2G |
| 1.7B | ~20G ⚠️ | ~6G | ~4G |
| 4B | >30G ❌ | ~10G | ~6G |
| 8B | ❌ | ~18G ⚠️ | ~9G ✅ |
| 14B | ❌ | ❌ | ~13G ✅ |
| 32B | ❌ | ❌ | ~20G ⚠️ 极限 |