使用LLaMA-Factory对GLM-4-9B-Chat进行LoRA微调

使用LLaMA-Factory对GLM-4-9B-Chat进行LoRA微调

在大模型应用日益普及的今天,如何快速、低成本地定制一个符合特定场景需求的语言模型,已经成为开发者和企业关注的核心问题。直接全参数微调动辄数十GB显存消耗,对大多数团队而言并不现实。而像 LoRA(Low-Rank Adaptation) 这样的高效微调技术,配合如 LLaMA-Factory 这类开箱即用的框架,正让“平民化”大模型定制成为可能。

本文将以 GLM-4-9B-Chat 为例,带你从零开始完成一次完整的 LoRA 微调流程——从环境配置、数据清洗到训练部署,最终得到一个可独立运行的专属模型。整个过程无需深入理解底层原理,也能在单卡 A10/A100 上顺利完成。


环境准备:搭建可编辑的开发环境

首先确保你的系统已安装 Python ≥ 3.10 和支持 CUDA 的 PyTorch 版本(推荐 torch==2.1.0+cu118 或更高)。考虑到国内网络环境,建议更换 pip 源以加速依赖下载:

python -m pip install --upgrade pip pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple 

接着克隆并安装 LLaMA-Factory。这里的关键是使用 -e 参数进行“可编辑安装”,这样后续若需调试源码或添加自定义组件也无需重新安装:

git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git cd LLaMA-Factory pip install -e ".[torch,metrics]" 
✅ 安装说明:[torch,metrics] 会自动拉取 Transformers、Datasets、Accelerate、Peft 等核心库,省去手动管理依赖的麻烦。

安装完成后执行以下命令验证是否成功:

llamafactory-cli --help 

如果输出帮助信息,则说明环境已就绪。此时你已经拥有了一个功能完整的大模型微调平台。


模型获取:通过 ModelScope 下载 GLM-4-9B-Chat

GLM-4-9B-Chat 是智谱 AI 推出的高性能对话模型,具备优秀的多轮交互与指令遵循能力。由于其未公开托管于 Hugging Face,我们需通过 ModelScope 获取。

创建脚本 download_glm4.py

from modelscope.hub.snapshot_download import snapshot_download model_dir = snapshot_download( 'ZhipuAI/glm-4-9b-chat', cache_dir='/root/models', # 可根据实际路径修改 revision='master' ) print(f"Model downloaded to: {model_dir}") 

运行后开始下载,模型体积约 14GB,通常需要 10–20 分钟。完成后记录下完整路径,例如 /root/models/ZhipuAI/glm-4-9b-chat,后续配置中将多次引用该路径。

⚠️ 注意事项:
- 需提前登录 ModelScope 账号并配置好认证密钥。
- 若提示权限错误,请检查是否已接受模型协议。

数据处理:构建高质量训练样本

LLaMA-Factory 支持多种数据格式,其中最常用的是 Alpaca 格式,它结构清晰且兼容性强。标准模板如下:

[ { "instruction": "请解释什么是机器学习", "input": "", "output": "机器学习是……", "system": "你是一位人工智能助手", "history": [ ["上一轮问题", "上一轮回答"] ] } ] 

字段含义明确:
- instructionoutput 是必填项;
- system 控制角色设定;
- history 支持多轮上下文建模。

单轮数据转换

假设原始数据为包含 "prompt""completion" 字段的 JSON 列表,可通过以下脚本完成转换:

import json import re file_name = "my_single_turn_data.json" system_prompt = "你是一个专业且富有同理心的AI助手" with open(f"./raw/{file_name}", "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 "你好,我是AI助手" in output_text: output_text = re.sub(r"^.*?\n", "", output_text).strip() converted.append({ "instruction": item["prompt"], "input": "", "output": output_text, "system": system_prompt, "history": [] }) with open(f"./processed/{file_name}", "w", encoding="utf-8") as f: json.dump(converted, f, ensure_ascii=False, indent=4) print(f"✅ {file_name} 已转换完成") 

这类清洗逻辑很常见——比如去除冗余引导语或特殊符号,能显著提升训练稳定性。

多轮对话提取

对于客服记录、访谈等多轮文本,关键是把历史对话作为上下文输入。示例代码如下:

import json from tqdm import tqdm file_name = "multi_turn_conversations.json" system_prompt = "你是一个耐心、专业的对话助手" with open(f"./raw/{file_name}", "r", encoding="utf-8") as f: conversations = json.load(f) converted = [] for conv in tqdm(conversations): dialogue = conv.get("conversation", []) if len(dialogue) < 1: continue history = [(turn["input"], turn["output"]) for turn in dialogue[:-1]] last_turn = dialogue[-1] converted.append({ "instruction": last_turn["input"], "input": "", "output": last_turn["output"], "system": system_prompt, "history": history }) with open(f"./processed/{file_name}", "w", encoding="utf-8") as f: json.dump(converted, f, ensure_ascii=False, indent=4) print(f"✅ 多轮数据 {file_name} 转换完成") 

这种设计能让模型学会基于上下文生成连贯回复,而不是每次都“失忆”。

数据集合并与注册

多个来源的数据可以统一合并成一个主文件:

import json merged = [] dataset_files = [ "single_turn_dataset_1.json", "single_turn_dataset_2.json", "multi_turn_conversations.json", "custom_instruction_tuning.json" ] for fname in dataset_files: with open(f"./processed/{fname}", "r", encoding="utf-8") as f: data = json.load(f) merged.extend(data) with open("./processed/combined_training_data.json", "w", encoding="utf-8") as f: json.dump(merged, f, ensure_ascii=False, indent=4) print("🎉 所有数据集已合并为 combined_training_data.json") 

然后将其注册到 LLaMA-Factory 中。编辑 data/dataset_info.json 添加条目:

{ "my_glm4_ft_data": { "file_name": "/path/to/LLaMA-Factory/data/processed/combined_training_data.json" } } 
✅ 提示:路径可以是绝对路径,也可以是相对于 data/ 目录的相对路径。

启动训练:配置 LoRA 微调任务

在项目根目录创建 YAML 配置文件 lora_sft_glm4.yaml

# 模型参数 model_name_or_path: /root/models/ZhipuAI/glm-4-9b-chat # 训练任务类型 stage: sft # Supervised Fine-Tuning do_train: true finetuning_type: lora # 使用 LoRA # LoRA 配置 lora_target: all # 应用于所有线性层(Q, K, V, O, FFN) lora_rank: 64 # 秩越高表达能力越强,但参数更多 lora_dropout: 0.05 # 正则化防止过拟合 lora_alpha: 16 # 缩放因子,一般设为 rank 的两倍左右 # 数据配置 dataset: my_glm4_ft_data template: glm4 # 使用官方 GLM 分词模板 cutoff_len: 2048 # 最大序列长度 max_samples: 5000 # 限制样本数便于调试 overwrite_cache: true preprocessing_num_workers: 16 # 输出设置 output_dir: saves/glm4-lora-sft/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 # 混合精度训练,节省显存 

几个关键点值得强调:
- lora_target: all 表示同时适配注意力层和前馈网络,适合复杂任务;
- fp16: true 在 A10/A100 上几乎无损还能减半显存占用;
- gradient_accumulation_steps: 8 相当于全局 batch size 达到 8,有助于梯度稳定。

启动训练只需一条命令:

cd LLaMA-Factory llamafactory-cli train lora_sft_glm4.yaml 

训练过程中终端会实时显示 loss 变化,同时日志也会写入 runs/ 目录,可用 TensorBoard 查看:

tensorboard --logdir=runs 

权重合并:导出可部署模型

训练结束后得到的只是一个 LoRA 适配器,不能独立运行。我们需要将其与原模型融合成一个完整的 .bin 文件。

新建 export_glm4_lora.yaml

model_name_or_path: /root/models/ZhipuAI/glm-4-9b-chat adapter_name_or_path: saves/glm4-lora-sft/checkpoint template: glm4 finetuning_type: lora export_dir: models/EmoGLM-4-9B-Chat export_size: 2 export_device: cpu export_legacy_format: false 

执行合并:

llamafactory-cli export export_glm4_lora.yaml 
💡 建议使用 CPU 合并,避免 GPU 显存溢出;虽然慢一些,但更可靠。

完成后,models/EmoGLM-4-9B-Chat 目录将包含标准 Hugging Face 模型结构,可直接用于推理。


效果验证:快速测试生成质量

编写简单脚本验证模型表现:

from transformers import AutoModelForCausalLM, AutoTokenizer model_path = "models/EmoGLM-4-9B-Chat" tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained(model_path, trust_remote_code=True, device_map="auto") query = "你能帮我写一首关于春天的诗吗?" inputs = tokenizer(query, return_tensors="pt").to("cuda") outputs = model.generate( **inputs, max_new_tokens=256, do_sample=True, temperature=0.7, top_p=0.9 ) response = tokenizer.decode(outputs[0], skip_special_tokens=True) print(response) 

观察输出是否体现出更强的风格一致性或领域倾向。如果明显优于原始模型,说明微调有效。


实战优化技巧与进阶建议

即使流程跑通了,仍有许多细节可以打磨。以下是我在实际项目中总结的一些经验:

场景解决方案
显存不足改用 QLoRA:设置 quantization_bit: 4 + finetuning_type: qlora,可在 24GB 显存下完成训练
训练太慢启用 FlashAttention:添加 attn_implementation: flash_attention_2(需 Ampere 架构及以上 GPU)
防止过拟合开启评估模式:设置 do_eval: trueval_size: 0.1,监控验证 loss 是否持续下降
多卡并行使用 DeepSpeed 或 DDP:配合 torchrun 分布式启动,注意增加 ddp_timeout: 180000

此外,LLaMA-Factory 还内置了 WebUI 界面,适合不熟悉命令行的用户:

llamafactory-cli webui 

访问 http://localhost:7860 即可通过图形界面上传数据、调整参数、启动训练,完全免去手写 YAML 的繁琐。


真正有价值的技术,不是最难懂的,而是最容易落地的。LLaMA-Factory 正是这样一个工具——它把复杂的分布式训练、内存优化、分词策略封装成简单的接口,让我们能把精力集中在数据质量和业务逻辑上。

无论是打造情感陪伴机器人、垂直行业问答系统,还是构建企业级智能体,这套方法都能帮你用极低成本迈出第一步。下一步,不妨试试用 QLoRA 在消费级显卡(如 RTX 3090/4090)上跑通整个流程,再接入 FastAPI 或 Gradio 构建服务接口,真正实现“让大模型为我所用”。

Read more

Flutter for OpenHarmony:Flutter 三方库 bluez 玩转 Linux 风格的蓝牙操作(蓝牙底层互操作)

Flutter for OpenHarmony:Flutter 三方库 bluez 玩转 Linux 风格的蓝牙操作(蓝牙底层互操作)

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net。 前言 随着鸿蒙(OpenHarmony)在工业互联网、智能座舱和物联网(IoT)领域的深入应用,与蓝牙设备的底层通信成为了许多开发者的刚需。在一些基于鸿蒙内核的特定工业版或车机版系统中,底层可能由于适配历史原因或分层设计,保留了类似 Linux 的 D-Bus 通信机制。 bluez 是一个专门用于与 Linux BlueZ 蓝牙协议栈通过 D-Bus 进行交互的 Dart 库。虽然对于普通的 HarmonyOS NEXT 手机开发我们通常使用官方的蓝牙插件,但在深度定制的鸿蒙发行版中,bluez 库为我们提供了一扇通往蓝牙底层控制的大门。 一、原理解析 / 概念介绍 1.1 基础概念 bluez 库并不直接操作蓝牙硬件,而是通过 D-Bus (Desktop Bus) 系统总线与系统级的蓝牙守护进程进行会话。 D-Bus

By Ne0inhk
claude code的安装和更新方法(macos)

claude code的安装和更新方法(macos)

目录 一、native安装:Run `claude install` 二、npm安装 1. 安装 node.js 2. 安装/更新 claude code 2.1. 检查当前版本和最新版本 3. Claude Code 自带更新命令: claude update 一句话总结:用npm安装claude code,用brew安装npm,用node来安装npm * homebrew是macos的系统级包管理器,类似app store的命令行版 * npm是node.js的包管理器,类似python的pip 【注意】 1)brew也可以安装claude code,而且能一条命令搞定安装和更新 (安装:brew install claude-code;更新:brew upgrade 一次性更新所有软件)

By Ne0inhk

Flutter 三方库 obs_websocket 的鸿蒙化适配指南 - 掌控远程直播导播、WebSocket 通讯实战、鸿蒙级直播中控专家

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 obs_websocket 的鸿蒙化适配指南 - 掌控远程直播导播、WebSocket 通讯实战、鸿蒙级直播中控专家 在鸿蒙跨平台应用处理专业级直播流控、远程导播指令或是构建自定义的直播中控台时,如何与业界标准的 OBS Studio 实现高效、实时的双向交互是关键。如果你追求的是在鸿蒙平板上一键切换场景、调整滤镜或监控直播帧率。今天我们要深度解析的 obs_websocket——一个完全基于 obs-websocket 协议构建的专业级客户端库,正是帮你打造“掌上导播间”的核心引擎。 前言 obs_websocket 是一套成熟的远程控制方案。它通过 WebSocket 隧道,将复杂的导播操作抽象为结构化的 JSON 指令。在鸿蒙端项目中,利用它你可以实现与直播机位(OBS 端)的深度联动,无论是实时获取推流状态,还是动态修改文字源内容,

By Ne0inhk
Flutter 三方库 workiva_analysis_options 的鸿蒙化适配指南 - 实现工业级的代码质量审计与 Linter 规约对齐、支持端侧工程架构健康度自动检测实战

Flutter 三方库 workiva_analysis_options 的鸿蒙化适配指南 - 实现工业级的代码质量审计与 Linter 规约对齐、支持端侧工程架构健康度自动检测实战

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 workiva_analysis_options 的鸿蒙化适配指南 - 实现工业级的代码质量审计与 Linter 规约对齐、支持端侧工程架构健康度自动检测实战 前言 在进行 Flutter for OpenHarmony 的企业级大型分布式项目开发时,如何统一上百名开发者的代码风格?简单的 analysis_options.yaml 默认配置往往无法满足金融、工业等严苛领域对代码健壮性、可维护性的极致要求。workiva_analysis_options 合集了来自顶级工程实践的代码静态分析规约。本文将探讨如何在鸿蒙端构建一道坚不可摧的代码质量防线。 一、原直观解析 / 概念介绍 1.1 基础原理 该库本质上是一套高度严谨的 Linter 指令集。它通过对 Dart 核心分析引擎建议集的精妙筛选,强制开启了涉及内存安全(Avoid Unnecessary

By Ne0inhk