如何在自有 GPU 上完成 Gemma 法律数据 LoRA 微调、权重合并到 vLLM 服务的全流程
2026/9/15 15:01:12 网站建设 项目流程

如何在自有 GPU 上完成 Gemma 法律数据 LoRA 微调、权重合并到 vLLM 服务的全流程

【免费下载链接】Nebius-CookbookA collection of projects showcasing RAG, agents, workflows, and other AI use cases项目地址: https://gitcode.com/GitHub_Trending/ne/Nebius-Cookbook

Nebius-Cookbook 的 legal-tech-fine-tuning-nebius-cloud 项目提供了一条完整可执行的路径:用 LoRA 对 Gemma 家族模型(默认google/gemma-4-E4B)在英国法律文本上做监督微调(SFT),把训练出的 LoRA 适配器合并回基础权重,再用 vLLM 以 OpenAI 兼容 API 对外提供服务。适用前提是:一台带 NVIDIA GPU 的机器(nvidia-smi可用,setup_and_train.sh按 H100 级机器假设,显存不足时可调整 batch size 或启用 QLoRA)、一个已获准访问 Gemma 受限(gated)检查点的 Hugging Face 账号与 token。完成本文步骤后,合并后的模型会以逻辑名legal-lorahttp://localhost:8100/v1上响应/v1/chat/completions请求。

准备条件

项目文档明确列出三项前置要求:

  • NVIDIA GPU,显存足以承载 Gemma 4 E4B 的训练或推理;
  • CUDA 对 PyTorch 可见,即nvidia-smi能正常工作;
  • Hugging Face 账号与 token,且该账号已接受 Gemma 检查点的许可协议(gated 模型)。token 通过HF_TOKEN环境变量或huggingface-cli login/hf auth login提供。

所有命令都在项目的 legal-tech-fine-tuning-nebius-cloud 目录内执行。仓库要求虚拟环境位于.venvrun.shserve.sh都依赖这个路径)。

搭建 Python 环境

文档给出两条安装路径,按机器现状二选一。

方式 A — 完整 VM 引导(适合全新虚拟机)。setup_and_train.sh会依次执行:sudo apt-get install安装构建工具与 Python 系统包、用nvidia-smi检查 GPU、创建.venv并安装 PyTorch cu124 与训练依赖栈、可选安装 flash-attn、通过hf auth login登录 Hugging Face,最后还会直接启动一次训练(数据默认legislation_qa_clean.jsonl,输出./gemma-legal-qa-clean-lora)。注意该脚本会使用sudo修改系统包,且结尾会执行微调,因此只建议在干净的专用 VM 上运行:

chmod +x setup_and_train.sh export HF_TOKEN=hf_your_token_here # 可选;否则走交互式登录 ./setup_and_train.sh

hf_your_token_here替换为你自己的 Hugging Face token。如果你只想要环境而不想让它替你跑训练,直接用方式 B。

方式 B — 手动最小安装(与 train_gemma.py 头部注释中的依赖要求一致),适合已有驱动和 Python 的机器:

python3 -m venv .venv source .venv/bin/activate pip install --upgrade pip pip install "torch>=2.3" torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124 pip install "transformers[chat_template]>=5.5.0" "trl>=1.0.0" "datasets>=3.0" accelerate peft bitsandbytes # Serving stack (if not already installed): pip install vllm fastapi uvicorn httpx openai

最后一行是服务与合并所需的栈:推理和合并至少需要torchtransformerspeftvllmfastapiuvicornhttpxopenai

一个需要留意的文档细节:setup_and_train.sh 中的注释指出,脚本默认MODEL_IDgoogle/gemma-4-E4B,但 E4B 检查点在 HF 上的实际模型 id 可能是google/gemma-3n-E4B(Gemma 3n 家族),并提示"换成你有访问权限的那个 id"。两个文档都默认google/gemma-4-E4B,若拉取该 id 失败,按脚本注释尝试google/gemma-3n-E4B,并以你账号实际可访问的 id 为准。

第一步:准备训练数据

原始法律条文文本在legislation.jsonl(每行一个法条记录)。用 convert_legislation_to_qa.py 把它转成 chat 风格的 JSONL——user 轮内嵌模拟检索的上下文块和问题,assistant 轮是从该块中抽取式生成的答案:

source .venv/bin/activate python convert_legislation_to_qa.py \ --input legislation.jsonl \ --output legislation_qa.jsonl

转换完成后需要一份训练文件。仓库自带一份人工整理好的示例 legislation_qa_clean.jsonl(约 160 行 chat 消息),可直接使用或自行整理。train_gemma.py接受的行格式包括:{"messages": [...]}(本项目推荐)、{"text": "..."}{"prompt": "...", "completion": "..."}以及 Alpaca 风格的instruction/output

第二步:运行 LoRA 微调

开始训练前,先停掉其他占用 GPU 的进程(例如正在跑的 vLLM),文档给出的命令是pkill -f 'vllm serve'——该命令会终止匹配的进程,只在确认没有其他需要保留的 GPU 任务时执行。

然后运行 train_gemma.py:

source .venv/bin/activate export HF_TOKEN=hf_your_token_here # 如基础模型需要鉴权 python train_gemma.py \ --model_id google/gemma-4-E4B \ --dataset_path legislation_qa_clean.jsonl \ --output_dir ./gemma-legal-qa-clean-lora \ --num_train_epochs 5 \ --learning_rate 1e-4 \ --max_seq_length 1024 \ --gradient_accumulation_steps 4

文档标注的常用参数:

参数用途
--load_in_4bit显存紧张时启用 QLoRA 式训练
--per_device_train_batch_sizeOOM 时调低(默认1
--use_lora/--lora_r/--lora_alphaLoRA 配置(默认 rank 16,alpha 32)

一个硬性条件:当使用messages格式数据、而 tokenizer 没有内置 chat template 时,chat_template.jinja必须存在于仓库根目录(本项目已提供 chat_template.jinja),否则训练会直接抛错。该模板同时用于后续 vLLM 服务,保证训练与推理的 Gemma chat 格式一致。

训练完成后,脚本日志会打印Training complete. Metrics: ...,最终模型与 tokenizer 保存到--output_dir(即./gemma-legal-qa-clean-lora)下的适配器文件。看到Fine-tuned model saved to: ...日志且该目录非空,即表示适配器已产出,可以进入合并步骤。

第三步:把 LoRA 适配器合并进基础模型

这套配置中 vLLM 加载的是合并后的完整权重,而不是在 serving 时挂 PEFT 适配器。用 merge_lora.py 执行合并:

source .venv/bin/activate python merge_lora.py \ --base_model google/gemma-4-E4B \ --adapter_path ./gemma-legal-qa-clean-lora \ --output_path ./gemma-legal-qa-clean-merged

脚本以 bfloat16 加载基础模型,加载--adapter_path中的 LoRA 适配器,执行merge_and_unload后把config.json、权重和 tokenizer 一并写入--output_path;如果chat_template.jinja存在,chat template 会被嵌入 tokenizer 配置,供 HF/vLLM 识别。

合并成功的判断方法:./gemma-legal-qa-clean-merged目录中存在config.json和权重文件。这也是下一步serve.sh启动前会做的检查。

第四步:用 vLLM 提供服务

serve.sh 以合并后的完整权重启动 vLLM,关键参数为:--served-model-name legal-lora(逻辑模型名)、--chat-template chat_template.jinja--chat-template-content-format string(文档注释说明:Gemma + OpenAI API 下用string可避免 system 文本泄漏进生成结果)、--dtype bfloat16--max-model-len 4096--gpu-memory-utilization 0.90

source .venv/bin/activate export MODEL_PATH=/absolute/path/to/gemma-legal-qa-clean-merged # 可选;默认取仓库根下的 ./gemma-legal-qa-clean-merged export VLLM_PORT=8100 # 可选 chmod +x serve.sh ./serve.sh

MODEL_PATH不设置时,脚本默认使用仓库根下的./gemma-legal-qa-clean-merged,因此只要合并步骤输出在该位置就无需设置;如把合并结果放在别处,替换MODEL_PATH为对应的绝对路径。

serve.sh启动时会先校验$MODEL_PATH/config.json是否存在,缺失会直接报错ERROR: Merged model not found at ...并退出——出现该报错说明合并步骤未完成或MODEL_PATH指错。

服务就绪后做两项验证:

# 列出模型,应能看到名为 legal-lora 的条目 curl -s http://localhost:8100/v1/models # 发起一次对话请求 curl -s http://localhost:8100/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "legal-lora", "messages": [ {"role": "system", "content": "You are a legal expert for UK legislation."}, {"role": "user", "content": "What is section 1 about?"} ], "max_tokens": 256, "temperature": 0.3 }'

/v1/models有响应说明 vLLM 已启动;/v1/chat/completions返回针对请求的 JSON 应答即代表合并后的模型可以正常推理。

常见问题排查

README 的 Troubleshooting 一节与 serve.sh、run.sh 的检查逻辑对应了四类问题:

  • 拉取模型报 401 / gated:设置HF_TOKEN,并在 Hugging Face 上接受该模型的许可协议。
  • 训练 OOM:加--load_in_4bit,调低--max_seq_length--per_device_train_batch_size,或增大--gradient_accumulation_steps
  • vLLM 起不来:确认已运行merge_lora.py,且MODEL_PATH(或默认目录./gemma-legal-qa-clean-merged)中包含config.json
  • 下游/health失败:先确认 vLLM 本身存活,curl -s http://localhost:8100/v1/models
  • --model_id拉取失败:如前述,脚本注释提示 E4B 检查点可能对应google/gemma-3n-E4B,换成你账号可访问的 id。

可选:一步启动 vLLM + FastAPI 前端

如果还需要项目自带的 FastAPI 法律路由层(/v1/legal/analyze/v1/legal/chat/health),不必手动起api.py,直接:

chmod +x run.sh ./run.sh

run.sh 会先在后台启动serve.sh,轮询直到http://localhost:8100/v1/models有响应(最长等待 600 秒),再以VLLM_BASE_URL=http://localhost:8100/v1启动 api.py 并等待其/health通过(最长 120 秒),随后打印 FastAPI、docs、vLLM 与 Health 的地址;Ctrl-C会同时停掉全部进程。环境变量VLLM_PORT(默认 8100)、API_PORT(默认 8000)、WITH_TUNNEL(置 1 时额外拉起 Cloudflare quick tunnel 暴露 HTTPS)均可按需覆盖。文档明确提示:首次加载模型时 vLLM 变健康需要几分钟,等待属正常现象。

至此,从法律 JSONL 到可被curl验证的 vLLM 服务就闭环了:legislation_qa_clean.jsonl./gemma-legal-qa-clean-lora(LoRA 适配器)→./gemma-legal-qa-clean-merged(合并权重)→legal-lora服务名下的:8100/v1端点。

【免费下载链接】Nebius-CookbookA collection of projects showcasing RAG, agents, workflows, and other AI use cases项目地址: https://gitcode.com/GitHub_Trending/ne/Nebius-Cookbook

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询