ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Qwen2.5-7B微调实战:从LoRA训练到vLLM部署全流程

Qwen2.5-7B微调实战:从LoRA训练到vLLM部署全流程 简介面向具备机器学习基础的研究人员与开发者这份基于 Qwen2.5-7B-Instruct 的微调实战指南完整呈现了在 AutoDL 平台使用 4090 云 GPU 训练大模型的实操路径。文档从 AutoDL 账号注册、实名认证与算力市场选型开始依次讲解 SSH 与 VSCode 远程连接、通过 HF-Mirror 镜像下载预训练模型、创建 conda 环境并安装 LLaMA-Factory 依赖等准备工作随后结合 LLaMA-Factory 可视化界面详细说明 LoRA 微调设置、自定义数据集接入、训练轮次调整、检查点保存位置和显存监控方式。文中还专门介绍 wandb 外部记录面板的注册与项目配置方法帮助读者在多次实验中系统追踪正确率与损失变化。资源为单个 PDF 文件压缩包大小约 2.28MB内容紧凑、步骤明确。已有 12378 人学习下载特别适合希望自主完成自然语言处理任务优化、模型性能提升的开发者按图索骥、动手复现。1. 基于Qwen2.5-7B-Instruct的微调为什么值得你亲自动手大模型微调这件事很多从业者卡在“看过无数教程一跑就报错”的尴尬阶段。基于Qwen2.5-7B-Instruct做微调恰恰是绕过这个尴尬的最短路径它参数规模适中7B单卡A100甚至双卡4090就能跑推理效果在同等量级开源模型里属于第一梯队而且官方对微调生态比如LoRA、全参微调的支持相当完善。换句话说如果你要在企业场景里做私有化部署、垂直领域知识增强或者只是想搞懂“大模型微调到底是什么、我的业务数据怎么灌进去”这个模型是风险最低的练手对象。这篇笔记会直接告诉你用什么框架、准备什么格式的数据、训练参数怎么设、跑起来之后怎么验证效果以及我实际踩过的坑。我不讲虚的尽量给能直接抄走的命令和配置。2. 微调原理与选型LoRA、QLoRA还是全参先看这张表再决定2.1 LoRA为什么是微调7B模型的第一选择大模型微调的经典矛盾是全参微调效果上限高但7B模型的完整权重就有约14GBBF16精度优化器状态AdamW需要一阶、二阶动量再翻几倍单卡显存轻松突破80GB。这还不算梯度。即便是企业级A100 80GB也只能勉强塞下一条样本训练速度还非常感人。LoRALow-Rank Adaptation的思路是冻结原模型权重只训练注入的低秩矩阵。以Qwen2.5-7B-Instruct为例它在每个线性层上额外加两组小矩阵训练时只更新这两组矩阵参数量通常只有原模型的0.5%到2%。这意味着显存占用大幅下降约等于推理显存加上小规模梯度的开销。训练速度快很多单卡409024GB就能跑起来。微调产物是一个很小的权重差值文件常见是几百MB便于保存、分发和回滚。QLoRA在LoRA基础上更进一步把原模型权重量化到4-bit再冻结训练时反量化计算梯度。这个方案能让你用更小的显存比如16GB跑7B微调代价是训练速度和稳定性略有折损。如果是第一次跑通流程我的建议是先用LoRABF16跑通再尝试QLoRA省显存。2.2 什么时候必须上全参微调什么时候可以无脑LoRA我不是全参微调反对者。如果你的场景是领域基座模型训练比如从零训练一个法律/医疗基座或者你需要根本性改变模型的输出风格改变语气、改写、抽取等任务类型也是可以的LoRA往往够用。但如果你要做的是让模型学到新的知识比如私有产品知识、内部文档LoRA低秩的假设会限制知识容量这时全参微调是更稳妥的路线。对比项LoRAQLoRA全参微调显存需求7BBF16/4bit约20GBBF16约12GB4bit约72GBBF16训练速度快较慢量化反算开销慢可学习参数量0.1%-2%0.1%-2%100%效果上限中高中高适合场景指令遵循、风格改写、垂直领域快速适配显存受限的轻量实验基座知识扩展、长期项目我的经验数值是单卡4090用LoRA跑7B序列长度2048、batch size 4稳定能跑。如果要用全参直接上云租8卡A100本地不用想。2.3 确定采用Qwen2.5-7B-Instruct作为基座的理由7B这个档位比较微妙再小比如1.5B在复杂指令遵循上能力明显不足再大比如14B/32B对硬件要求又上一个台阶。Qwen2.5-7B-Instruct在数学、代码、多语言指令遵循上的表现配合它的开源协议使它成了企业私有化部署里曝光度很高、经过大量实战验证的选项。有一个容易忽略的细节Qwen2.5-7B-Instruct原生支持的系统提示词System Prompt处理能力很强。微调时如果不给模型配一条清晰的系统提示词很多业务数据的目标行为是学不到的。这个问题在第四节展开。3. 搭建可复现的微调环境从显卡驱动到transformers版本这一步最容易翻车3.1 环境清单和版本搭配不是越新越好微调7B模型环境版本搭配的优先级比任何参数都高。我见过太多人把PyTorch升到最新版结果和transformers不兼容一跑就报错。这里给出我反复验证过的一组稳定搭配操作系统Ubuntu 20.04/22.04GPUNVIDIA 4090 或以上显存24GB最佳显存16GB需要上QLoRACUDA 12.1注意是驱动支持的CUDA版本不是torch版本里的Python 3.10PyTorch 2.1.2transformers 4.43.0peft 0.10.0accelerate 0.30.0datasets 2.19.0flash-attn 2.4.0训练7B时强烈建议装安装命令如下注意用pip安装时锁定版本号避免“顺手升级到最新版”带来的兼容性灾难。# 建议在干净的conda环境中操作 conda create -n qwen-finetune python3.10 -y conda activate qwen-finetune # 安装PyTorch注意cu121对应CUDA 12.1 pip install torch2.1.2 torchvision0.16.2 torchaudio2.1.2 --index-url https://download.pytorch.org/whl/cu121 # 安装微调核心依赖 pip install transformers4.43.0 peft0.10.0 accelerate0.30.0 datasets2.19.0 # flash-attn 如果编译失败可以参考官方GitHub用预编译wheel pip install flash-attn2.4.0注意flash-attn 安装报错是高频坑常见原因是CUDA版本和PyTorch编译环境不一致。如果预编译失败不要硬刚编译可以直接从flash-attn官方仓库找对应CUDA/PyTorch版本的预编译wheel包下载安装。3.2 单卡脚本基础启动项从Hugging Face下载模型容易卡住的替代方案大多数人的网络环境从Hugging Face拉模型会卡在权重下载阶段。常见的替代做法是用ModelScope魔搭拉权重或者直接从ModelScope下载后本地加载。Qwen2.5-7B-Instruct在ModelScope上同步发布国内网络环境下用ModelScope比Hugging Face顺利得多。先安装ModelScope客户端pip install modelscope然后写一个下载脚本# download_model.py from modelscope import snapshot_download # 使用模型ID直接下载到指定目录路径按自己需求改 model_dir snapshot_download( Qwen/Qwen2.5-7B-Instruct, local_dir/data/models/qwen2.5-7b-instruct ) print(f模型已下载到: {model_dir})下载完成后本地加载时直接把model_name_or_path参数指到上述路径即可。这里有一个判断技巧如果目录里有safetensors文件就能直接做BF16加载如果只有bin文件那是PyTorch旧格式加载速度和对新框架的兼容性都会差一些建议优先用safetensors版。3.3 验证环境的最小推理模型加载成功不等于能训练做任何微调之前先确认基座模型能在当前环境正常做一次推理。这一步能筛掉90%的环境问题。代码很短但逻辑要完整加载分词器、加载模型、拼对话模板、生成输出。# test_inference.py from transformers import AutoModelForCausalLM, AutoTokenizer model_path /data/models/qwen2.5-7b-instruct # 加载分词器和模型低资源环境可加 device_mapauto tokenizer AutoTokenizer.from_pretrained(model_path, trust_remote_codeTrue) model AutoModelForCausalLM.from_pretrained( model_path, torch_dtypeauto, # Qwen2.5推荐用bfloat16加载 device_mapauto, trust_remote_codeTrue ) model.eval() # 按Qwen2.5的官方chat模板拼格式这是换行符号后保留样式的关键 messages [{role: user, content: 11?}] text tokenizer.apply_chat_template( messages, tokenizeFalse, add_generation_promptTrue ) inputs tokenizer([text], return_tensorspt).to(model.device) outputs model.generate(**inputs, max_new_tokens128) print(tokenizer.decode(outputs[0], skip_special_tokensTrue))这段代码里有两个细节值得注意。第一apply_chat_template是Qwen2.5系列对外接微调最友好的接口它会把系统提示词和对话历史按训练时一致的模板渲染避免你手动拼模板时漏掉特殊token。第二torch_dtypeauto会读取模型配置文件里的默认精度Qwen2.5-7B-Instruct默认BF16bfloat16不要用torch_dtypetorch.float16强行改FP16在损失值比较低的时候容易出现溢出问题。如果这段代码输出结果正常环境就算打通了。接下来把GPU利用率打开nvidia-smi你会发现模型加载后显存占用约14GB属于正常现象不用惊慌。4. 制作微调数据集把业务数据变成Qwen2.5能学习的对话模板4.1 数据格式必须是ChatML结构普通文本一行扔进去没有任何效果这是新手最容易翻车的地方。大模型微调不是把业务数据丢进文本文件就行Qwen2.5-7B-Instruct的训练数据是按对话结构组织的一个完整样本长这样{ messages: [ {role: system, content: 你是一位专业的医疗客服请用简洁、准确的语言回答患者问题。}, {role: user, content: 我最近总是头晕可能是什么原因}, {role: assistant, content: 头晕的原因很多建议先测量血压注意是否伴随耳鸣、视物旋转等症状。如果持续不缓解请尽快就医。} ] }注意系统提示词不是可选项。我用过一个客服数据集没有写system角色的数据模型微调后确实能流畅回复但完全丢失了客服该有的克制语气变得像是闲聊机器人。后来补上系统提示词效果立刻正常。4.2 用脚本把现有数据转成对话格式并提供中英混合场景的处理方案很多企业内部数据是问答对、工单用户描述 客服回复、工单标签。写一个转换脚本把这些“半成品”变成上面的JSON格式是微调前最耗时的环节。下面是一个通用的转换思路# convert_to_chat.py import json import random # 假设你有问答对列表 [{question: ..., answer: ...}, ...] qa_pairs [ {question: 如何重置密码, answer: 请点击个人中心-设置-重置密码按短信验证码提示操作。}, # ... 你的业务数据 ] system_prompt 你是一家企业管理系统的智能助手回答用户问题时请分步骤说明保证准确。 chat_data [] for item in qa_pairs: sample { messages: [ {role: system, content: system_prompt}, {role: user, content: item[question]}, {role: assistant, content: item[answer]} ] } chat_data.append(sample) # 输出为JSONL文件每行一个样本transformers的datasets库可以直接加载 with open(train_data.jsonl, w, encodingutf-8) as f: for sample in chat_data: f.write(json.dumps(sample, ensure_asciiFalse) \n) print(f转换完成共 {len(chat_data)} 条样本)关于数据量不同来源的经验差距很大。如果集内样本和基座已有能力差距不大比如只是让模型学一套固定的客服话术500到1000条高质量样本就够了。如果涉及新的知识比如企业内部产品FAQ2000到5000条是常见区间。数据质量永远大于数量一条乱标的数据污染效果远大于十条好数据。4.3 数据清洗三原则去重、去噪、检查上下文长度清洗这一关能省掉训练时大量莫名其妙的损失不下降问题。去重用fuzzywuzzy或sentence-transformers做文本相似度去重。重复数据会让模型过度学习某几个固定回答泛化能力下降。去噪把数据里的HTML标签、多余换行和特殊符号清理掉。噪声会直接拉高训练损失loss而且特别隐蔽——训练曲线看着在下降但验证集效果就是差。检查上下文长度数据里system user assistant总token长度要低于你训练时设置的max_seq_length。通常训练前写一段代码统计每条样本的token数把超过目标长度的样本单独挑出来决定截断还是拆分。# check_length.py from transformers import AutoTokenizer tokenizer AutoTokenizer.from_pretrained(/data/models/qwen2.5-7b-instruct) max_len 2048 bad_samples [] with open(train_data.jsonl, r, encodingutf-8) as f: for idx, line in enumerate(f): data json.loads(line) # 直接用分词器计算整条messages转为token后的长度 tokenized tokenizer.apply_chat_template( data[messages], tokenizeTrue, add_generation_promptFalse ) if len(tokenized) max_len: bad_samples.append((idx, len(tokenized))) print(f超过{max_len}长度的样本数: {len(bad_samples)}) for idx, length in bad_samples[:10]: print(f样本 {idx}: {length} tokens)超过长度上限的样本通常两种处理法一是截断user或assistant内容保留问题关键和回答关键二是拆成多条子样本。但优先建议修改原始数据本身——很多超长是因为回答里堆了大量无关背景精简后效果更好。5. 用LoRA跑通训练全流程train.py的每一行参数都给你注释清楚5.1 核心训练脚本建议直接抄然后重点看超参训练脚本是整篇的“抄作业”核心。我提供一个经过验证的LoRA训练脚本输出目录和评估指标一并写进去可以直接在单卡4090上运行。# train.py import os from datasets import load_dataset from transformers import ( AutoModelForCausalLM, AutoTokenizer, TrainingArguments, Trainer, DataCollatorForSeq2Seq ) from peft import LoraConfig, get_peft_model, TaskType # 基础配置 model_path /data/models/qwen2.5-7b-instruct data_path train_data.jsonl output_dir ./output_qwen_lora # 加载数据集4.2节中生成的jsonl文件加载为huggingface Dataset dataset load_dataset(json, data_filesdata_path, splittrain) # 按9:1划分训练和验证固定种子保证可复现 split_dataset dataset.train_test_split(test_size0.1, seed42) tokenizer AutoTokenizer.from_pretrained(model_path, trust_remote_codeTrue) # Qwen2.5不需要设置pad_token但为了保险没有pad_token时用eos_token if tokenizer.pad_token is None: tokenizer.pad_token tokenizer.eos_token def format_func(example): 把数据集里的messages字段转成apply_chat_template需要的结构 text tokenizer.apply_chat_template( example[messages], tokenizeFalse, add_generation_promptFalse ) return {text: text} # 格式化并分词 formatted_dataset split_dataset.map(format_func, remove_columns[messages]) def tokenize_func(example): outputs tokenizer( example[text], truncationTrue, max_length2048, paddingFalse, return_tensorsNone ) # 因果语言模型标签等于输入本身 outputs[labels] outputs[input_ids].copy() return outputs tokenized_dataset formatted_dataset.map(tokenize_func, batchedFalse, remove_columns[text]) # 加载Qwen2.5-7B-InstructBF16节省显存 model AutoModelForCausalLM.from_pretrained( model_path, torch_dtypeauto, # 读取模型配置默认BF16 device_mapauto, trust_remote_codeTrue ) # LoRA配置 lora_config LoraConfig( task_typeTaskType.CAUSAL_LM, r16, # 秩常用8~3216是均衡值 lora_alpha32, # LoRA缩放系数常见设为r的2倍 lora_dropout0.05, # 防止过拟合 target_modules[q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj] ) model get_peft_model(model, lora_config) # 统计可训练参数量确认生效 model.print_trainable_parameters() # 训练参数 training_args TrainingArguments( output_diroutput_dir, per_device_train_batch_size4, per_device_eval_batch_size4, gradient_accumulation_steps8, learning_rate2e-4, num_train_epochs2, logging_steps10, save_steps200, eval_strategysteps, eval_steps100, save_total_limit2, bf16True, # Ampere架构及以上建议BF16 lr_scheduler_typecosine, warmup_ratio0.03, remove_unused_columnsFalse, report_tonone, # 不接wandb时用none避免报错 load_best_model_at_endTrue, metric_for_best_modeleval_loss, ) trainer Trainer( modelmodel, argstraining_args, train_datasettokenized_dataset[train], eval_datasettokenized_dataset[test], data_collatorDataCollatorForSeq2Seq(tokenizertokenizer, paddingTrue), ) trainer.train() # 保存LoRA权重保存后是一个几百MB的adapter文件 trainer.save_model(output_dir) tokenizer.save_pretrained(output_dir)5.2 超参选择的逻辑lr、epoch数、batch size之间怎么权衡训练脚本里的超参不是乱设的每个数字背后都有实践经验一项一项权衡过的。r16和lora_alpha32是7B模型上尝试过的均衡组合。r越大可学习参数量越多但过大会让可学习参数量动辄2%以上LoRA的低秩约束反而失效容易过拟合。lora_alpha是缩放系数常见设置为r的两倍过大容易导致初始损失跳得很高。learning_rate2e-4是LoRA训练的第一梯队取值。全参微调常用1e-5LoRA因为只更新小参数学习率可以适当提高。我第一次跑的时候用3e-5损失下降非常慢后来提到2e-4才正常。num_train_epochs2是个有意思的数字。微调数据量在千条级别时2个epoch左右模型就能学会模式超过3个epoch灾难性遗忘的风险明显增加。“多跑几个epoch效果更好”是十足的外行直觉我实测发现第2个epoch结束时验证损失最低到第3个epoch验证损失明显反弹。per_device_train_batch_size4是最保守的4090配置。加上gradient_accumulation_steps8等效batch size为32。不要小看梯度累积——LoRA训练时大batch size能提供更稳的梯度估计对最终收敛效果影响明显。5.3 训练过程的观测点loss曲线和验证集上的抽样输出训练过程中不用频繁打断。主要看两个东西训练损失train loss和验证损失eval loss。正常现象是训练损失稳步下降验证损失下降但偶尔抖动整体趋势向下。不正常现象有两种训练损失下降缓慢且数值偏高比如一直停在2.0以上多半是学习率太小或数据噪声太大。训练损失下降但验证损失不降反升这是过拟合的信号应减少epoch数或加大数据量。验证集的作用不只是在训练结束时看个分数。我建议在每个save_steps时保存的checkpoint上手动跑几条验证集样本实际看模型输出。数值指标和真实输出感受经常不一致人工抽查是最后一道关。6. 微调避坑指南环境、数据、训练三层常见坑的排查手记6.1 训练loss是nan或直接OOM训练刚开始就报loss nan通常不是运气问题而是数值精度或数据异常的确定性结果。原因之一Qwen2.5-7B的logits值域比较大FP16训练时损失容易溢出。解决办法是换BF16训练这也是我建议bf16True而不用FP16的原因。原因之二数据里有脏字符或异常emoji。解决办法是回到数据清洗环节把非UTF-8字符和过长的连续符号清除。OOM则多半是显存估算不准batch size设到8或164090直接爆掉。解决办法是把batch size调回4序列长度从2048降到1024或启用QLoRA。6.2 模型训练完只会复读问题或者回答前后不连贯这类“复读机”现象常见原因是调整了模型配置导致位置编码positional encoding参数混乱但更常见的根因是微调数据里assistant角色的回答格式和基座模型原始训练数据不一致。Qwen2.5-Instruct在原始训练里assistant回答前面有特殊token|im_start|assistant如果你在转换数据时手动拼接模板漏掉了这个token或者加错了位置模型学到的就不是正常对话而是学会了复读。解决办法是坚持用tokenizer.apply_chat_template来渲染数据不手动拼模板。这也解释了为什么前面的数据转换代码里我坚持用这个方法。6.3 模型直接输出乱码或不认识的字符乱码通常发生在中文语料里排查顺序是检查数据集文件本身编码是否UTF-8有没有BOM头。检查分词器在encode和decode时是否完整不要在训练脚本里手动做tokenizer.decode(tokenizer.encode(...))的截断操作。检查pad_token是否设置。很多文本在padding时用了默认|endoftext|以外的字符decode时就出现乱码——前面脚本里那句tokenizer.pad_token tokenizer.eos_token执行的正是这一层防护。6.4 多卡训练时NCCL超时单卡能跑多卡就Hang住很多人的机器不只一张卡想用accelerate或deepspeed多卡训练结果往往卡在NCCL初始化阶段。常见报错是NCCL error: timeout。原因一般是多卡间的NVLink或PCIe带宽不足、网络接口配置错误或者NCCL版本和驱动不匹配。解决路径有三条先用nvidia-smi确认多卡都可见设置环境变量NCCL_P2P_DISABLE1和NCCL_IB_DISABLE1试试禁用对等传输虚拟机或云主机常见最后确认是NCCL_SOCKET_IFNAME没指定到正确的网卡如eth0。6.5 训练完加载LoRA权重报错训练完成后加载adapter_model.bin进去报错十有八九是base model路径对不上。LoRA权重记录的是base模型里每个target模块的形状如果你加载时换了别的模型比如从Qwen2.5-7B换成了Qwen2.5-14B形状对不上就会报错。解决办法是训练和加载时base模型必须完全一致包括同版本的safetensors文件不要用AutoModelForCausalLM图省事让框架自动选其他权重。7. 微调后的合并、量化与vLLM部署一条能落地的推理链路训练完成只是开始真实业务要的不是一个adapter文件而是一个能对外服务的推理接口。这里讲一条我习惯的落地链路合并LoRA权重 → 转成GGUF本地/边缘端或用vLLM部署服务端。7.1 合并LoRA权重到原始模型这一步改变你之后所有部署方式合并LoRA权重是用peft库一行方法完成的。合并后的模型是一个完整的7B模型可以直接被vLLM、TGI这类框架加载无需在推理时额外接adapter。# merge_lora.py from peft import PeftModel from transformers import AutoModelForCausalLM, AutoTokenizer base_model_path /data/models/qwen2.5-7b-instruct lora_path ./output_qwen_lora merged_save_path ./merged_model_qwen # 加载原始模型 base_model AutoModelForCausalLM.from_pretrained( base_model_path, torch_dtypeauto, device_mapcpu, # 合并用CPU更稳不会因显存不足中断 trust_remote_codeTrue ) tokenizer AutoTokenizer.from_pretrained(base_model_path, trust_remote_codeTrue) # 加载LoRA权重并合并 model PeftModel.from_pretrained(base_model, lora_path) merged_model model.merge_and_unload() # 保存合并后的模型 merged_model.save_pretrained(merged_save_path, safe_serializationTrue) tokenizer.save_pretrained(merged_save_path)合并时用CPU完成的好处是避免显存波动导致中断。合并完成后检查比对用同一个问题在合并前后各跑一遍如果输出差异不明显除了风格或知识点变好说明合并正常。7.2 把合并模型转成GGUF面向Ollama本地部署和边缘端设备的选择如果微调后的模型要在本地单机或者内网环境没有GPU里跑GGUF是更常见的序列化格式。转换工具目前主推llama.cpp仓库里的convert_hf_to_gguf.py脚本。转换过程很机械但有一个坑一定要带上--vocab-type参数Qwen2.5用的是bpe如果漏了这参数分词器会不匹配。# 使用llama.cpp转换脚本注意指定词表类型 python convert_hf_to_gguf.py ./merged_model_qwen \ --outfile ./qwen2.5-7b-instruct-finetuned.gguf \ --outtype q8_0 \ --vocab-type bpe转换完成后用Ollama创建Modelfile指定文件路径就可以本地加载# Modelfile FROM ./qwen2.5-7b-instruct-finetuned.gguf TEMPLATE {{- if .System }}|im_start|system {{ .System }}|im_end| {{- end }}|im_start|user {{ .Prompt }}|im_end| |im_start|assistant SYSTEM 你已经被微调为特定领域的助手请按设置要求回答。这个Modelfile要特别留神TEMPLATE必须严格按Qwen2.5的chatml格式写否则推理时系统提示词和对话历史会乱套。Ollama本地部署的优势是不需要Python环境CPU也能跑适合企业内部小规模试用。7.3 vLLM部署满足高并发API服务的方案如果微调模型要接API对外服务vLLM是开源生态里吞吐量最稳的方案。它有专门的--served-model-name参数和--enable-prefix-caching等优化开关部署命令如下# 部署微调合并后的模型开启前缀缓存提升批量对话效率 python -m vllm.entrypoints.openai.api_server \ --model ./merged_model_qwen \ --tokenizer ./merged_model_qwen \ --served-model-name qwen-finetuned \ --port 8000 \ --gpu-memory-utilization 0.9 \ --max-model-len 8192 \ --enable-prefix-caching部署后用curl发一条请求验证curl http://localhost:8000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: qwen-finetuned, messages: [{role: user, content: 请用一句话介绍你自己}], max_tokens: 128 }实测下来vLLM的--enable-prefix-caching在多轮对话场景下能把吞吐提升将近一倍强烈建议开启。--max-model-len要根据实际数据长度调整8192够用如果实际业务上下文不超过2048建议改小一些显存利用率会更高。7.4 一个技巧用GGUF量化后的模型做快速回归评测不必每次启动大模型微调完成后的验证环节很多人的习惯是启动vLLM再逐条跑测试费时费力。我的习惯是先在本地用Ollama加载GGUF量化版利用它的极低开销做快速回归。量化到q8_0时效果损失很小但启动速度比vLLM快得多适合批量跑几百条验证集。如果验证集输出符合预期再启动vLLM做正式的API服务。这一条习惯帮我省下大量时间——毕竟微调本身经常要迭代验证环节越轻量越好。希望这个流程能帮到你。本文还有配套的精品资源点击获取
返回列表