使用LLaMA-Factory对GLM-4-9B进行LoRA微调
在当前大模型落地应用的浪潮中,如何以较低成本让通用语言模型适配垂直领域任务,成为开发者关注的核心问题。全参数微调虽效果显著,但动辄数百GB显存的需求令人望而却步。幸运的是,像LoRA(Low-Rank Adaptation)这类参数高效微调技术的出现,使得在单张消费级GPU上完成大模型定制化训练成为可能。
本文将以GLM-4-9B-Chat模型为例,结合LLaMA-Factory这一功能强大的开源框架,带你完整走通从环境搭建、数据准备到模型训练与部署的全流程。整个过程无需编写复杂训练逻辑代码,通过简洁的配置即可实现高质量微调,尤其适合科研实验或产品原型开发。
环境配置:构建稳定可复现的训练基础
任何高效的微调流程都离不开一个干净且依赖明确的运行环境。我们建议优先使用conda创建独立虚拟环境,避免与系统已有包产生冲突。
conda create -n glm4-lora python=3.10 conda activate glm4-lora接下来升级 pip 并设置国内镜像源以加速依赖安装:
python -m pip install --upgrade pip pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple随后克隆 LLaMA-Factory 项目仓库并安装核心组件:
git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git cd LLaMA-Factory pip install -e ".[torch,metrics]"这里的-e表示“可编辑模式”安装,便于后续调试源码;[torch,metrics]是预定义的可选依赖组,会自动拉取 PyTorch 生态链中的关键库,如transformers、datasets和peft等。
⚠️ 注意事项:
- 推荐使用 Python ≥ 3.9 和 PyTorch ≥ 2.0。
- 若使用 A10/A100 显卡,确保 CUDA 驱动和 cuDNN 版本兼容。
完成上述步骤后,你的本地开发环境已具备运行大模型微调任务的基本能力。
获取模型权重:通过 ModelScope 下载 GLM-4-9B
由于 GLM 系列模型由智谱 AI 开源发布,需借助其官方平台 ModelScope 完成模型下载。首先安装客户端工具并登录账号:
pip install modelscope modelscope login登录成功后,创建脚本download_glm4.py来自动化获取模型文件:
from modelscope import snapshot_download model_dir = snapshot_download( 'ZhipuAI/glm-4-9b-chat', cache_dir='/data/models', # 可根据实际磁盘情况调整路径 revision='master' ) print(f"模型已成功下载至: {model_dir}")执行该脚本:
python download_glm4.py整个模型约14GB,在网络状况良好的情况下通常需要 10–30 分钟完成下载。虽然 LoRA 微调仅更新少量参数,但仍需完整加载原始权重用于前向传播和梯度计算,因此必须保留全部模型文件。
数据集处理:统一格式为 Alpaca 结构
LLaMA-Factory 支持多种输入格式,其中Alpaca 格式因其结构清晰、兼容性强,被广泛用于指令微调任务。其标准结构如下:
[ { "instruction": "解释什么是机器学习", "input": "请用高中生能理解的语言描述", "output": "机器学习是……", "system": "你是一个专业的AI助手", "history": [ ["上一轮问题", "上一轮回答"] ] } ]所有字段将由框架根据glm4模板自动拼接为完整的 prompt 序列。下面展示两种常见场景的数据转换方式。
单轮对话数据清洗与转换
假设原始数据为简单问答对,存储于single_turn_raw.json中:
[ {"prompt": "介绍一下你自己", "completion": "我是EmoLLM……"} ]我们可以编写脚本来标准化格式,并加入系统提示与文本清洗逻辑:
import json import re input_file = "../datasets/single_turn_raw.json" output_file = "./processed/converted_single.json" system_prompt = "你是一个情感陪伴型AI助手,请温柔且富有同理心地回应用户。" with open(input_file, 'r', encoding='utf-8') as f: raw_data = json.load(f) converted = [] for item in raw_data: output_text = item["completion"] # 清理不必要的自指语句和符号 if '🐳' in output_text: output_text = output_text.replace('🐳', '') if '好,我是' in output_text or '你好,我是' in output_text: output_text = re.sub(r'^[^。\n]*[,,][^。\n]*[。|\n]', '', output_text).strip() converted.append({ "instruction": item["prompt"], "input": "", "output": output_text, "system": system_prompt, "history": [] }) with open(output_file, 'w', encoding='utf-8') as f: json.dump(converted, f, ensure_ascii=False, indent=4) print(f"✅ 单轮数据转换完成:{output_file}")这类清洗策略在构建人格化助手时尤为重要——去除机械化的自我介绍模板,有助于提升回复自然度。
多轮对话历史提取
对于心理咨询、客服记录等多轮交互数据,关键在于正确划分“当前轮”与“历史上下文”。例如原始数据格式为:
[ { "conversation": [ {"input": "你觉得今天天气怎么样?", "output": "挺好的,阳光明媚。"}, {"input": "你喜欢户外运动吗?", "output": "喜欢啊,尤其是爬山。"} ] } ]应将最后一轮作为目标任务,其余作为history输入:
import json from tqdm import tqdm input_file = "../datasets/multi_turn_conversations.json" output_file = "./processed/converted_multi.json" system_prompt = "你是一个乐观开朗的朋友,请自然流畅地参与聊天。" with open(input_file, 'r', encoding='utf-8') as f: conversations = json.load(f) converted = [] for conv in tqdm(conversations): turns = conv["conversation"] if len(turns) < 1: continue last_turn = turns[-1] history = [(t["input"], t["output"]) for t in turns[:-1]] converted.append({ "instruction": last_turn["input"], "input": "", "output": last_turn["output"], "system": system_prompt, "history": history }) with open(output_file, 'w', encoding='utf-8') as f: json.dump(converted, f, ensure_ascii=False, indent=4) print(f"✅ 多轮数据转换完成:{output_file}")这种处理方式能让模型更好地理解上下文依赖关系,在真实对话场景中表现更连贯。
合并与注册数据集
若已完成多个子集的转换,可将其合并为单一文件以便管理:
import json merged = [] files_to_merge = [ "converted_single.json", "converted_multi.json", "self_cognition.json", "emotional_support.json" ] for fname in files_to_merge: with open(f"./processed/{fname}", 'r', encoding='utf-8') as f: data = json.load(f) merged.extend(data) with open("glm4_finetune_dataset.json", 'w', encoding='utf-8') as f: json.dump(merged, f, ensure_ascii=False, indent=4) print("🎉 所有数据集已合并为 glm4_finetune_dataset.json")然后编辑LLaMA-Factory/data/dataset_info.json,添加新数据集引用:
"glm4_custom_ft": { "file_name": "glm4_finetune_dataset.json" }注意:此处路径若为相对路径,则相对于data/目录解析。推荐使用绝对路径以避免加载失败。
配置并启动 LoRA 训练任务
现在进入最关键的一步——配置训练参数。在项目根目录下新建 YAML 文件lora_glm4_sft.yaml:
model_name_or_path: /data/models/ZhipuAI/glm-4-9b-chat stage: sft do_train: true finetuning_type: lora lora_target: all lora_rank: 64 lora_dropout: 0.05 use_rslora: false use_dora: false dataset: glm4_custom_ft template: glm4 cutoff_len: 2048 max_samples: 5000 overwrite_cache: true preprocessing_num_workers: 16 output_dir: saves/glm4-lora-ft/checkpoint logging_steps: 10 save_strategy: epoch plot_loss: true overwrite_output_dir: true per_device_train_batch_size: 1 gradient_accumulation_steps: 8 learning_rate: 1e-4 num_train_epochs: 5 lr_scheduler_type: cosine warmup_ratio: 0.1 fp16: true do_eval: true val_size: 0.1 per_device_eval_batch_size: 1 eval_strategy: epoch eval_steps: 50几个关键参数值得特别说明:
lora_target: all:表示对 Q、K、V 投影层及 MLP 中的线性模块均注入 LoRA 适配器。相比只作用于注意力头(如q_proj,v_proj),这种方式表达能力更强,适用于知识密集型任务。lora_rank=64:秩越高,适配矩阵容量越大。对于 9B 规模的模型,64 是一个经验上的平衡点,兼顾性能与稳定性。fp16 + gradient_accumulation_steps=8:即使每卡 batch size 仅为 1,也能累积等效 batch size 达 8,有效缓解小批量训练带来的梯度噪声问题。
保存配置后,直接运行训练命令:
llamafactory-cli train lora_glm4_sft.yaml训练过程中终端将实时输出 loss 曲线、学习率变化及 GPU 利用率信息。每个 epoch 结束后,checkpoint 将自动保存至指定目录。
导出可部署的融合模型
训练完成后,LoRA 适配器是以增量形式存在的轻量权重,不能独立推理。我们需要将其“合并”回原始模型中,生成一个可以直接加载的完整模型。
新建导出配置文件export_glm4_lora.yaml:
model_name_or_path: /data/models/ZhipuAI/glm-4-9b-chat adapter_name_or_path: saves/glm4-lora-ft/checkpoint template: glm4 finetuning_type: lora export_dir: models/EmoGLM-4-9B-Lora-Merged export_size: 2 export_device: gpu export_legacy_format: false执行合并操作:
llamafactory-cli export export_glm4_lora.yaml最终在models/EmoGLM-4-9B-Lora-Merged目录下你会看到标准 Hugging Face 模型结构:
├── config.json ├── generation_config.json ├── tokenizer_config.json ├── pytorch_model.bin └── ...这个模型可以轻松集成到 FastAPI、Gradio 或 vLLM 等服务框架中,实现在线 API 调用或本地交互式体验。
图形化界面进阶:WebUI 免代码训练
如果你更习惯可视化操作,LLaMA-Factory 还提供了基于 Gradio 的 WebUI 界面:
CUDA_VISIBLE_DEVICES=0 llamafactory-cli webui访问http://localhost:7860即可打开控制面板,在浏览器中完成以下操作:
- 选择模型路径与微调方法
- 指定数据集并预览样本
- 调整 LoRA 参数与训练超参
- 实时监控 Loss 曲线与硬件资源占用
WebUI 会在后台自动生成对应的 YAML 配置文件并启动训练任务,极大降低了初学者的入门门槛,也方便团队协作时共享配置。
在整个实践中,LLaMA-Factory 展现出极高的工程成熟度:它封装了复杂的底层细节(如 DataCollator 构建、PeftModel 包装、混合精度调度),让我们能够专注于数据质量和任务设计本身。通过这一流程,你可以快速打造出面向特定场景的专业模型,比如医疗问答机器人、教育辅导助手或心理健康陪伴者。
未来还可进一步探索:
- 使用QLoRA + 4-bit 量化将显存需求压缩至 20GB 以内;
- 借助TensorBoard深入分析训练动态;
- 构建Gradio Demo对外展示微调成果。
随着高效微调技术不断演进,大模型的“平民化”时代正加速到来。而像 LLama-Factory 这样的开源工具,正是推动这场变革的重要引擎。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考