作者:Unsloth Team、Synthetic Data Hackathon Team、AMD AI Group
如果你关注开源 LLM,欢迎为Unsloth 仓库[1]点亮⭐。本文示例还使用 Meta 的 Synthetic-Data-Kit[2]。
用单卡、batch size = 128 去微调70B 模型并不常见。本文将演示如何在单卡AMD GPU 上,使用 Unsloth 对 Llama-3.3-70B 进行监督式微调(SFT),并基于 LoRA(16-bit)优化模型推理能力。关键条件包括:
1.充足显存(VRAM):192GB 支持更大序列与批大小;
2.Unsloth 的自动优化:包括梯度卸载(offload)与内核级优化等机制,使高负载配置更稳定可行。
要点:依托高显存与 Unsloth 的优化,可以在单卡上实现 70B 级模型的高效 SFT。
我们将先利用模型生成合成数据(逻辑题、答案与CoT(Chain-of-Thought,显式推理链)),再用这些数据对同一模型进行微调,以提升其在相关任务上的表现。流程概述:
1.使用 LLM 将文档转化为带推理链的 QA;
2.使用该数据对同一 LLM 进行 SFT。
图 1:整体流程(Pipeline Overview)
实验使用 Llama-3.3-70B-Instruct 与 Unsloth,在 192GB 显存 条件下配置如下:
Seq length:1024
Batch size:128
LoRA(16-bit),rank = 64
说明:Unsloth 会自动启用多项优化(如自动梯度卸载与内核级加速),以较小开销支撑上述配置。原本面向 QLoRA(4-bit)的思路,在高显存条件下可直接采用 LoRA(16-bit)方案。
Llama-3.3(70B)微调可装入 41GB
注:标题中的“41GB”结论源自不同方案的上下文长度测试。具体测量条件与计算细节未在此段展开,建议参阅所引Unsloth 文章获取完整实验前提:https://unsloth.ai/blog/llama3-3
Llama-3.3(70B)最大上下文长度对比
注:为评估内存占用,Unsloth 在 80GB A100 上测试 Llama-3.3-70B-Instruct,对全部线性层(Q、K、V、O、gate、up、down)做 4-bit QLoRA,rank = 32、batch size = 1,并将序列统一 padding 至指定最大长度,以模拟长上下文微调负载。
图 2:长上下文示例(来源:Unsloth)
以下步骤演示如何从“下载逻辑题 PDF”,到“让同一模型生成并解答逻辑题且给出推理过程”:
1.下载 含逻辑推理内容的 PDF;
2.使用Llama-3.3-70B 生成带推理链的微调数据集;
3.准备数据集 并搭建LoRA(16-bit) 微调流水线;
4.运行实验。
说明:本文展示的是可复现的高性能入门方案。包含约 30–50 条对话样本,旨在帮助快速上手与激发思路,而非大规模基准测试。
我们使用 Synthetic-Data-Kit(简称 SDKit)。它可通过配置文件或 CLI 调用本地 LLM或托管端点,完成从文档到微调数据的完整链路:解析 → 生成 QA / CoT → 质量评审 → 导出训练格式。
关键思路:用 LLM 生成 QA,再用 LLM 作为评审(LLM as a judge)筛选高质量样本。
图 3:Synthetic-Data-Kit 数据生成流程
1)启动 vLLM 服务
在本实验中,由于显存充裕,我们将 70B 模型以 vLLM 单卡部署为本地端点,让 SDKit 连接该端点生成数据。
vllm serve Unsloth/Llama-3.3-70B-Instruct --port 8001 --max-model-len 48000 --gpu-memory-utilization 0.85
2)编写 config.yaml
SDKit 读取该配置,重点包括输入/输出路径、vLLM 端点地址,以及系统提示词(prompts)(指导 Llama 生成带难度与领域标签的逻辑推理 QA,并可生成 CoT)。
示意配置可能存在缩进或粘贴问题,请参考最新版[3]。
3)连通性检查
synthetic-data-kit -c config.yaml system-check
4)准备开源逻辑题 PDF
#create the repositories where we will use the PDF and save the examples tomkdir -p logical_reasoning/{sources,data/{input,parsed,generated,curated,final}}cd logical_reasoningwget -P sources/ -q --show-progress "https://www.csus.edu/indiv/d/dowdenb/4/logical-reasoning-archives/logical-reasoning-2017-12-02.pdf" "https://people.cs.umass.edu/~pthomas/solutions/Liar_Truth.pdf"cp sources/* data/input/
5)解析文档(ingest)
synthetic-data-kit ingest ./data/input/ --verbose
6)从文本生成 QA / CoT-QA
synthetic-data-kit -c ../config.yaml create ./data/parsed/ --type qa --num-pairs 15 --verbose# ORsynthetic-data-kit -c ../config.yaml create ./data/parsed/ --type cot --num-pairs 15 --verbose
--num-pairs 控制每份文档的样本数量;
若未指定,SDKit 会尽可能多地产生可用样本。
7)用 LLM 做质量评审
synthetic-data-kit -c ../config.yaml curate ./data/generated/ --threshold 7.0 –verbose
8)导出为微调格式
synthetic-data-kit save-as ./data/curated/ --format ft –verbose
要点:SDKit + 本地 vLLM 端点,可快速把 PDF 批量转成带推理且已质检的微调数据。
现在我们已获得 QA 样本,可将其转换为 Unsloth 训练所需格式。
我们提供了格式转换脚本,将每条 message 封装为 conversation 结构,与常见 Chat 格式一致。
图 4:数据转换细节(Data Conversion Details)
完成后,可得到一个合并后的 JSON,可直接用于训练。
⚠️警告:开始训练前,请确保 vLLM 服务已停止,否则可能导致 OOM(显存溢出)。
💡提示:在 ROCm 环境下,必须显式指定 dtype(如 bf16 或 fp16)。
1)导入依赖
from unsloth import FastLanguageModelfrom unsloth.chat_templates import get_chat_template, standardize_sharegpt, train_on_responses_onlyfrom trl import SFTConfig, SFTTrainerfrom transformers import DataCollatorForSeq2Seq, TextStreamer
2)设置模型、Tokenizer 与 LoRA 参数
本实验使用以下设置:
Seq_len:1024
LoRA(16-bit)参数:r = 64、lora_alpha = 64
Use_gradient_checkpointing = "unsloth"
采用仅训练回答部分的策略(即仅优化 assistant 段落)
示例训练函数如下:
def train_model_rocm(model, tokenizer, dataset, max_seq_length):"""Train model with ROCm-optimized settings"""# Setup trainer with ROCm-friendly settings and proper data handling trainer = SFTTrainer(model=model,tokenizer=tokenizer,train_dataset=dataset,dataset_text_field="text",max_seq_length=max_seq_length,data_collator=DataCollatorForSeq2Seq(tokenizer=tokenizer, padding=True),packing=False,args=SFTConfig(per_device_train_batch_size=1,gradient_accumulation_steps=4,warmup_steps=5,num_train_epochs=1,learning_rate=1e-4,logging_steps=1,optim="adamw_8bit", # Pure torch optimizerweight_decay=0.01,lr_scheduler_type="linear",seed=3407,output_dir="logical_reasoning_rocm_outputs",report_to="none",bf16=True,dataloader_pin_memory=False,remove_unused_columns=True, # Remove unused columns to avoid tensor issuesgradient_checkpointing=True,dataloader_num_workers=0, # Single worker for ROCm stability),)# Train only on responsestrainer = train_on_responses_only(trainer,instruction_part="<|start_header_id|>user<|end_header_id|>\n\n",response_part="<|start_header_id|>assistant<|end_header_id|>\n\n",)print(f"\n🔥 Starting ROCm training on {len(dataset)} examples...")FastLanguageModel.for_training(model)trainer_stats = trainer.train()return trainer_stats
3)启动训练
执行以下命令开始训练:
FastLanguageMode.for_training(model)trainer_stats=trainer.train()
4)保存权重与合并模型
训练完成后,保存LoRA 权重 与合并后的 16-bit 模型,便于后续推理与部署:
def save_model_rocm(model, tokenizer):"""Save the trained model"""lora_path = "logical_reasoning_rocm_lora"model.save_pretrained(lora_path)tokenizer.save_pretrained(lora_path)# Save merged modelmerged_path = "logical_reasoning_rocm_merged"model.save_pretrained_merged(merged_path, tokenizer,save_method="merged_16bit")print(f"✅ Merged model saved to: {merged_path}")
在单卡 AMD GPU 环境下约 30 分钟内完成该示例任务(约 50 条样本、1 个 epoch),可根据数据规模调整运行时长。
建议进一步尝试更多数据集,并在 Unsloth 上发起新的实验运行。
致谢
本文由以下同事协作完成:
Daniel Han、Michael Han、Sanyam Bhutani、Eda Zhou、Guruprasad MP、Hamid Shojanazeri、Mark Saroufim、Anita Katahoire、Emre Guven
参考资料
[1] Unsloth 仓库:https://github.com/unslothai/unsloth
[2] Synthetic-Data-Kit :https://github.com/meta-llama/synthetic-data-kit
[3]最新版本:https://github.com/edamamez/Unsloth-AMD-Fine-Tuning-Synthetic-Data/tree/main/AIAC
推荐阅读:

