最近大模型圈子里,DeepSeek的热度一直居高不下。从我自己的实际体验来说,它确实是目前少有的,既能让人在普通消费级显卡上跑起来,又能用API低成本接入到业务里的开源模型。很多朋友问我,网上那么多“从入门到精通”的教程,为什么一上来还是懵?答案很简单:大部分教程只教了怎么聊天,没教怎么把模型用起来。这篇就把我踩过的坑和实际跑通的经验整理出来,从部署、微调到应用开发,完整走一遍DeepSeek的使用全流程。
无论你是刚开始接触大模型的开发者,还是已经在用其他模型想换到DeepSeek的工程师,这篇内容都能给你一条清晰可执行的路线。文中会涉及具体的命令、参数和代码,也会解释每个关键步骤为什么要这么做,避免你照着抄还报错,出了问题无从下手。
1. 从入门到精通,先建立对DeepSeek的系统认知
1.1 DeepSeek到底是什么,为什么大家都在聊
DeepSeek本质上是一系列开源大语言模型的统称。和很多只能通过API访问的闭源模型不同,DeepSeek的模型权重是公开的,你可以下载到本地,部署在自己的服务器上,甚至可以拿去微调,根据自己的业务做定制。这个大前提决定了它和普通“调用接口”的玩法有本质区别。
从模型结构上看,DeepSeek采用的是目前主流的Transformer架构,但在注意力机制、激活函数、推理优化上做了不少改动。尤其是它引入了混合专家架构的版本,可以在不显著增加单次推理成本的情况下,把模型总参数量做得很大。通俗一点说,它像是一个公司里有很多专业小组,每次提问只激活相关的小组来回答,而不是所有人都围过来,效率自然高不少。
很多开发者选择DeepSeek,看重的不只是“免费开源”这个标签,更是它背后完整的生态。官方提供了支持多卡并行训练的代码,社区也有大量量化版本和部署工具,这意味着从研究学习到生产落地,都有成熟的方案可以选。哪怕你只是想在个人电脑上跑一个能联网、能总结文档的私人助手,DeepSeek也是目前性价比极高的选择。
1.2 本地跑的DeepSeek和API调用,怎么选
很多人第一次接触DeepSeek时会纠结:到底是用官方API,还是自己在本地部署一套?我的建议是先想清楚你的使用场景。
如果你只是想快速验证效果,或者开发一个对响应速度、并发要求不高的应用,直接用官方API最省事。API方式不需要管显存、不需要管模型权重,一个Key就能用。同时,API版本往往经过了服务端优化,回答质量和稳定性都更有保障,你自己部署的版本如果调参不当,反而可能不如API。
但如果你有数据隐私方面的要求,比如业务数据不允许出内网,或者你需要对模型做深度定制微调,那就必须本地部署。本地部署的另一个好处是,单次调用的边际成本几乎为零,跑大批量离线任务时优势非常明显。我在实际项目中就遇到过这样的情况:用API批量处理几万条文本,费用直接成了成本大头,换了本地部署之后,除了电费和硬件折旧,基本没有额外开销。
我做了一个简单的对比表,方便你快速判断:
| 对比项 | 本地部署 | API调用 |
|---|---|---|
| 启动成本 | 需要GPU设备 | 注册即可 |
| 部署难度 | 中等,需要懂Linux和Python | 低,几行代码 |
| 数据隐私 | 数据完全本地 | 需要信任服务方 |
| 单次调用成本 | 极低 | 按Token计费 |
| 并发能力 | 取决于硬件配置 | 高,弹性扩容 |
| 微调支持 | 完全支持 | 通常不支持或受限 |
一句话总结:图省心选API,图可控选本地。如果预算允许,两者可以同时用——本地做开发和批量任务,API做高并发线上服务,各取所长。
1.3 学习路线图和核心能力拆解
“从入门到精通”听起来很大,但拆开来看,真正需要掌握的只有四个模块:模型原理、部署运行、微调训练、应用开发。这四个模块是层层递进的关系。
模型原理阶段不需要你从头复现一篇论文,只需要理解几个关键概念:参数量、量化、上下文长度、温度参数、模型架构。这些概念决定了你在部署时选哪个版本、跑起来后怎么调参。很多人跳过这一步,直接去跑模型,结果遇到“为什么我的模型回答这么慢”“为什么输出内容总是重复”这类问题,毫无头绪,根源就是对原理不了解。
部署运行是动手的开始。你要学会用工具把模型启动起来,至少能跑通一次推理,并且搞清楚显存占用、并发能力这些关键指标。我建议先从Ollama这种傻瓜式工具入手,跑通了再上vLLM这类专业推理框架,循序渐进。
微调训练是整个学习路线的分水岭。很多人觉得微调很难,但实际上现在LoRA这类参数高效微调技术已经把门槛降得很低,一张消费级显卡就能跑中小模型的微调。关键不是会不会写训练代码,而是懂数据、懂评估,知道什么样的数据集能让模型变好,以及怎么判断微调后的效果。
应用开发是终极目标。你需要学会把模型封装成API,和知识库检索、工具调用结合起来,做一个真正能解决实际问题的应用。到了这一步,你才算真正把DeepSeek“用起来”了。
2. 本地部署:从零跑起一个DeepSeek
2.1 硬件到底要什么配置
部署DeepSeek第一步,先确认你的硬件。很多人总是问“我的电脑能不能跑”,说实话,模型不是只有固定大小的,DeepSeek有不同尺寸的版本,小到1.5B,大到几百B,硬件需求天差地别。
以我常用的几个模型为例,简要说明一下显存需求:
| 模型规模 | 最低显存(FP16) | 量化为4bit后显存 | 适合场景 |
|---|---|---|---|
| 1.5B | 约3GB | 约1GB | 轻量任务、移动端 |
| 7B | 约14GB | 约5GB | 日常对话、小规模应用 |
| 14B | 约28GB | 约9GB | 较高智能度需求 |
| 32B | 约64GB | 约18GB | 复杂推理、智能体 |
注意,这里说的显存不只是模型权重本身,还要算上KV Cache(推理过程中的键值缓存)和运行时开销。你装好模型后直接看任务管理器会发现实际占用比理论值高不少,这就是KV Cache吃显存的结果。
如果显存不够,优先考虑量化。量化就是把模型权重从高精度浮点数压缩到低精度整数,比如从FP16压到INT4,显存占用直接减小到原来的四分之一左右。代价是回答精度有轻微损失,但对大部分场景来说,这个损失完全在可接受范围内。我自己在跑7B模型时就长期用4bit量化版,体感上回复质量和原版差距很小。
CPU也是可以跑的,但速度非常感人。我用纯CPU跑7B模型,生成一个几百字的回答要等两三分钟,基本只能用来测试,实际应用建议还是配一块至少8GB显存的显卡。
2.2 用Ollama快速部署:最简单直观的启动方式
如果你之前没有部署过任何大模型,我的建议是从Ollama开始。Ollama是一个开源的本地模型运行工具,它把模型下载、依赖管理、API服务这些事全部封装好了,你只需要几条命令就能跑起一个完整的对话模型。
安装Ollama没什么好说的,到官网下载对应操作系统的安装包,装完打开终端验证一下:
ollama --version看到版本号就说明安装成功。接下来拉取DeepSeek的模型:
ollama run deepseek-r1:7b这条命令会自动下载模型权重,下载完成后直接进入交互式对话界面。你可以直接在终端里和模型聊天,体验一下效果。
这只是跑起来了,真正干活的时候我们需要启动一个HTTP服务,让其他程序能调用它。先启动服务:
ollama serve然后在另一个终端里用curl测试接口:
curl http://localhost:11434/api/generate -d '{ "model": "deepseek-r1:7b", "prompt": "写一首关于秋天的五言绝句", "stream": false }'返回的JSON里就会包含模型的生成结果。从这一步开始,DeepSeek就不再是一个只能在终端里聊天的玩意,而是一个可以通过HTTP协议访问的AI服务了。
Ollama最大的优点是省心,但代价是自定义空间小。适合刚入门时快速跑通流程,生产环境建议用下一节讲的更专业的工具。
2.3 用vLLM部署生产级服务:吞吐量和并发才是重点
当你要把模型对接到真实业务,遇到并发请求时,Ollama会逐渐力不从心,因为它的推理引擎对显存利用效率和并发优化做得不够极致。这个时候就该上vLLM了。vLLM是一个专门为大模型推理服务设计的高性能框架,核心优势在于它实现了连续批处理和优化的显存管理,可以让一张显卡同时服务更多请求,吞吐量比朴素实现高出好几倍。
用vLLM启动DeepSeek模型,首先需要把模型权重下载到本地。可以从模型托管平台拉取,这里以合适的开源托管平台为例,用Python下载:
pip install modelscope modelscope download --model deepseek-ai/DeepSeek-R1-Distill-Qwen-7B --local_dir ./deepseek-7b下载完成后,写一个Python脚本启动vLLM服务:
from vllm import LLMServer实际上更常用的是直接命令行启动:
python -m vllm.entrypoints.openai.api_server \ --model ./deepseek-7b \ --served-model-name deepseek-7b \ --tensor-parallel-size 1 \ --gpu-memory-utilization 0.9 \ --port 8000参数含义如下:
--model指定本地模型路径;--tensor-parallel-size指定使用的显卡数量,单卡就写1;--gpu-memory-utilization表示允许vLLM占用的显存比例,我一般留一点余量给其他程序,设成0.9比较稳妥;--port是服务监听端口。
启动成功后,它会提供一个兼容OpenAI接口规范的API地址,这意味着你后续可以用标准的OpenAI SDK来调用它,代码切换成本非常低。
生产环境我强烈推荐vLLM,虽然配置过程比Ollama复杂一些,但换来的是稳定性和并发能力。如果业务量很大,还可以在vLLM前面加一层负载均衡,后面挂多张AI服务器,做成集群。
2.4 部署后的性能验证与API测试
无论你用哪种方式部署,部署完成后都要做一次完整的性能验证,确保它能满足你的实际需求。验证包括四个指标:响应延迟、吞吐量、显存占用、回答质量。
先用简单的curl测试响应延迟:
curl http://localhost:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "deepseek-7b", "messages": [{"role": "user", "content": "你好,请介绍一下你自己"}], "max_tokens": 200 }'记录从发送请求到收到完整回复的时间。注意这里说的是完整收到时间,不是流式输出的首字时间,两者意义不同。如果做对话类应用,用户第一印象看的是首字时间,也就是模型开始吐出第一个字的速度;如果做离线批量分析,更看重整体吞吐量。
吞吐量可以用现成的压力测试工具,比如oha,或者写一个简单的并发脚本模拟50个请求同时打过来,看vLLM的处理能力和响应时间变化。正常情况下,7B模型单卡吞吐量每秒能在几百到上千Token之间,具体取决于显存和输入长度。
显存占用用nvidia-smi实时监控:
nvidia-smi -l 1回答质量方面,我建议准备一组包含不同难度的测试题,从简单问答、代码生成到逻辑推理,每类至少测10次,人工观察结果是否稳定,有没有前后不一致或者明显错误的情况。这个测试集以后每次换模型、调参数都会用到,值得一开始就整理好。
部署完成后,最好把启动命令和测试结果存档,方便以后排查问题。我见过很多人在模型升级后忘了记录旧版本的参数,出了问题连回滚的配置都找不回来。
3. 微调:把通用模型调成你的专属专家
3.1 什么时候需要微调,什么时候不需要
微调不是万能的,也不是所有场景都必须做。很多问题用提示词工程就能解决,根本不用动模型权重,做了微调反而可能让模型丧失一部分通用能力。我建议先按这个顺序判断:能不能靠提示词?不能的话,能不能靠RAG检索增强?还不能,再考虑微调。
提示词工程是最低成本的手段。比如你希望模型按特定格式输出,只要在提示词里写清楚,一般就能生效。RAG适合知识密集型任务,比如回答特定领域的问题,模型不需要改变自己的说话风格,只需要能从外部文档里找到准确信息。
只有当模型的行为模式本身需要改变时,才需要微调。举例来说,如果你要让模型学会一种完全新的对话风格,或者让它根据你的产品数据输出特定结构化的JSON,而这些用提示词很难稳定约束,微调就是更合适的方案。
我给微调场景做了个分界线,你可以参考:
| 情况 | Prompt工程 | RAG | 微调 |
|---|---|---|---|
| 模型知识不足 | 没用 | 推荐 | 不行 |
| 输出格式不符合要求 | 试一下 | 不行 | 推荐 |
| 需要学习专有术语和风格 | 效果有限 | 部分帮助 | 推荐 |
| 需要推理逻辑上的定制 | 不行 | 不行 | 推荐 |
简单的理解就是:知识缺失找RAG,行为模式改变找微调。两者也可以结合使用,实际生产项目中往往是“RAG提供事实,微调塑造风格”。
3.2 微调前的准备:数据集构建
微调效果好不好,数据集占了八成决定因素。很多人上来就问训练参数怎么设置,但真正该花时间的是整理数据。
DeepSeek微调普遍采用指令微调格式,每条样本包含“提示”和“回答”两部分。以对话类任务为例,常见的数据格式是JSON:
[ { "instruction": "你是某电商平台的客服,请根据用户的问题给出专业回复。", "input": "我昨天买的手机今天发现有碎屏,可以退货吗?", "output": "您好,非常抱歉给您带来不好的体验。根据我们的售后政策,签收后7天内出现非人为损坏的质量问题,支持退换货。请您通过订单页面申请售后,上传相关凭证,我们将尽快为您处理。" } ]注意,这里的instruction是对模型行为的总约束,每条样本都可以一样,也可以写不一样但方向一致。input是用户输入,output是期望模型输出的内容。
数据质量比数量更重要。几千条高质量数据,效果往往好过几万条低质量数据。低质量数据包括:答非所问的、语义重复的、含有明显错误的。我见过一个项目微调后模型频繁输出幻觉信息,排查到最后发现是训练集中混入了一批明显行文敷衍的示例,模型照葫芦画瓢也学会了敷衍。
数据集构建完毕,还需要按比例划分训练集和验证集,一般建议9:1或8:2。验证集不能和训练集有重复,否则评估结果会很虚。
3.3 LoRA微调实战:用最少显存跑通全流程
LoRA是大模型微调领域里程碑式的技术。它的核心思想很巧妙:冻结原始模型的全部参数,只额外训练一小部分低秩矩阵维度上的参数。这样一来,训练时显存占用大幅降低,一张消费级显卡就能微调7B甚至更大的模型。
我常用的微调框架是LLaMA-Factory,它对DeepSeek系列模型支持得不错,内置了LoRA的训练流程。首先安装:
pip install llama-factory然后在项目根目录里准备好上述的数据集,编辑训练配置文件,我用的是一个简化版本:
model_name_or_path: ./deepseek-7b dataset: custom_dataset finetuning_type: lora lora_rank: 32 lora_alpha: 64 learning_rate: 2e-4 num_train_epochs: 3 per_device_train_batch_size: 2 gradient_accumulation_steps: 4 max_length: 1024 output_dir: ./deepseek-7b-lora每个参数的调法:
lora_rank是低秩矩阵的维度,32是比较通用的起点,太大了显存涨,太小了表达能力不足;lora_alpha是缩放系数,一般设成lora_rank的2倍,这是经验值;learning_rate取2e-4这个量级,LoRA训练用太大会不稳定;per_device_train_batch_size要看显存余量来设置,7B模型4bit量化后单卡能放下2左右;gradient_accumulation_steps用于模拟更大的批次,4步累加相当于实际批次为8;max_length控制输入长度,太长显存会爆,太短会截断重要内容。
配置完成后,执行训练命令:
llamafactory-cli train config.yaml训练过程中要留意日志里每个epoch的loss值。loss不一定要降到很低,但要保持平滑下降,如果出现明显波动,说明学习率设高了或者数据有问题,应该早点停下去改。
训练完成后,LoRA适配器参数会保存到output_dir目录。在应用阶段,可以把它和基础模型合并起来,也可以直接加载使用。用LLaMA-Factory合并:
llamafactory-cli export \ --model_name_or_path ./deepseek-7b \ --adapter_name_or_path ./deepseek-7b-lora \ --finetuning_type lora \ --export_dir ./deepseek-7b-mered合并后的模型可以直接用vLLM部署,和普通模型一样使用。
3.4 微调后的评估与部署
微调完成不等于大功告成,必须经过系统评估才能上线。最直接的评估方法是准备一批模型没见过的问题,对比微调前后模型的回答,看是否达到了你的预期。
我建议把评估指标分为两类:客观指标和主观指标。客观指标包括BLEU、ROUGE这类文本相似度分数,但说实话,对生成式模型这些指标参考价值有限。更实用的主观指标是你自己定义的评价维度,比如“回答格式是否规范”“术语使用是否准确”“是否越权回答无关问题”。把这些维度做成打分表,找三个人分别打分,取平均值,比任何自动化指标都靠谱。
有一个比较容易踩的坑:微调会让模型变得“懒”——因为它学习的样本里很多回答都是简短空洞的,模型可能选择用最省事的方式回复。如果你的业务需要详细回答,数据里就必须多放详细示例,并且在评估时特别关注输出长度是否合理。
评估通过后,把微调后的模型部署到生产环境。部署方式与基础模型完全一致,只是把模型路径换成合并后的目录。我建议先灰度一个小流量,观察一段时间再全量替换,因为有些问题可能在高并发场景下才会暴露。
4. 开发:用DeepSeek搭出真实应用
4.1 应用开发的主流架构:从裸模型到Agent
只会部署和调用模型,还称不上“开发”。真正把DeepSeek变成产品,需要理解当前应用层的主流架构。
最简单的架构是直接调用模型API,把用户提问发给模型,再把回答返回给用户。适合demo和功能简单的聊天工具,但如果用户经常问一些超出模型知识范围的问题,这种架构体验会很差。
进阶一点的架构是RAG。它的思路是,在模型回答问题前,先从外部知识库里检索和问题相关的文档片段,拼接到提示词里一起交给模型。这样模型就能“临时翻书”再回答,大大减少幻觉现象。
再往上就是Agent。Agent的核心是让模型具备“工具调用”能力,它可以根据用户任务自动决定什么时候调用搜索引擎、什么时候查询数据库、什么时候执行代码。DeepSeek本身对函数调用有不错的理解能力,配合流式输出和工具注册,可以做出很实用的自动化助手。
三种架构可以组合使用,实际项目中经常是“RAG+Agent”并存:Agent负责理解任务和拆解步骤,RAG负责提供领域知识,模型负责最终生成。理解了这个大局,下面几个小节才有意义。
4.2 写一个本地的对话API服务
不管用什么架构,第一步都是把本地模型封装成自己的服务。vLLM已经提供了开箱即用的OpenAI兼容接口,但如果你需要加一些自定义的逻辑,比如记录日志、检查敏感词、统计Token用量,还是写一个自己的服务更靠谱。
用FastAPI搭建一个轻量的对话接口,思路大概是这样的:
from fastapi import FastAPI from pydantic import BaseModel from openai import OpenAI app = FastAPI() client = OpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY") class ChatRequest(BaseModel): message: str max_tokens: int = 500 @app.post("/chat") def chat(req: ChatRequest): resp = client.chat.completions.create( model="deepseek-7b", messages=[{"role": "user", "content": req.message}], max_tokens=req.max_tokens ) content = resp.choices[0].message.content return {"reply": content}这段代码要点有两个。第一,base_url指向的是之前启动的vLLM服务地址,因为vLLM提供的是OpenAI格式接口,所以直接用OpenAI的Python库就能连上,非常方便。第二,api_key随便填个占位符就行,因为本地服务不做鉴权,如果你要把服务暴露到内网或者公网,一定要在vLLM背后加一层真正的API Key校验。
写成服务之后,就可以被前端、手机App、自动化脚本任意调用了。我在实际项目中经常把服务再包一层,加上用户会话历史管理,这样模型就能记住上下文中的对话内容,而不是每次都从零开始。
4.3 把DeepSeek接进知识库:RAG实战
RAG是让模型变成“懂业务”的必修课。我以一个简单的企业内部规章制度问答系统为例,讲一下完整实现。
第一步,把文档切分成块。文本不能太长也不能太短,太长了检索不精准,太短了语义不完整。一般按500到1000字切一块,每块之间留一部分重叠,防止切断完整语义。
第二步,用向量化模型把文本块转成向量。向量模型和DeepSeek是两回事,它专门负责把文本映射成高维向量,把语义相近的文本映射到邻近的位置。我常用的是bge或gte系列模型,体积小,效果也不错。
第三步,把用户问题也转成向量,去向量数据库里做相似度检索,找到最相关的几个文本块。
第四步,把检索到的文本块和用户问题一起塞进提示词,教模型基于这些材料回答,不要编造。
下面是一个简化的RAG检索函数:
import chromadb from sentence_transformers import SentenceTransformer vec_model = SentenceTransformer('./bge-base-zh') client = chromadb.PersistentClient(path="./chroma_db") collection = client.get_collection("docs") def retrieve(query, top_k=3): q_vec = vec_model.encode(query).tolist() results = collection.query(query_embeddings=[q_vec], n_results=top_k) docs = "请仅根据以下资料回答问题:\n\n" for i, doc in enumerate(results['documents'][0]): docs += f"[{i+1}] {doc}\n" return docs把retrieve返回的拼接文字作为系统提示词的一部分,再调DeepSeek,就能得到一个结合知识库的回答。RAG好不好用,很大程度取决于向量检索的质量,而不是模型本身。所以如果发现回答不准,优先检查文档切分和向量模型选型。
4.4 打造一个小型Agent工具调用
DeepSeek有函数调用能力,能让我设计一个智能工具助手,让模型自己在合适的时机调用外部工具。举个例子,做一个“信息查询Agent”,可以调用天气查询和计算器两个工具。
首先,在API请求里定义可用工具,用JSON Schema描述:
[ { "type": "function", "function": { "name": "get_weather", "description": "查询指定城市的天气", "parameters": { "type": "object", "properties": { "city": {"type": "string", "description": "城市名"} }, "required": ["city"] } } }, { "type": "function", "function": { "name": "calculator", "description": "执行四则运算", "parameters": { "type": "object", "properties": { "expression": {"type": "string", "description": "数学表达式"} }, "required": ["expression"] } } } ]把用户问题和工具列表一起发给模型,模型会输出一个工具调用请求,而不是直接回答。开发人员拿到工具名称和参数后,执行真实函数,再把执行结果作为额外消息交给模型,让它生成最终回复。
这个流程就是Agent最基本的形态。扩展思路也很清晰:多接入几个工具,比如查数据库、发邮件、创建工单,这个Agent就能处理越来越多的真实工作。需要注意,工具调用对模型的上下文长度要求比较高,大模型要在多个工具之间做选择,容易遗漏细节。所以工具描述最好精确,参数越少越好,模型的判断就越准确。
5. 常见问题与避坑实录
5.1 部署阶段的高频报错
部署DeepSeek最常见的坑,我按出现频率排了个序。
第一个是显存不足。有时候看模型权重大小觉得没问题,但一启动就直接OOM。解决方法有三个:换更小尺寸的模型、用量化版本、减小max_length和并发数。Ollama默认会按模型情况自动分配,vLLM可以调整gpu-memory-utilization参数解决。
第二个是端口被占。服务启动失败,日志提示address already in use。这时候查看端口占用情况:
lsof -i:8000找到占用进程,关掉之后再启动。注意不要随便kill系统关键进程,看准PID再操作。
第三个是模型加载慢或者一直卡住。这种情况多数是因为第一次加载需要做权重转换,还要构建推理缓存,第二次启动会快很多。如果每次都很慢,检查磁盘读写速度,模型放在机械硬盘上会明显拖慢加载。
还有一个常见问题是模型版本和推理框架不兼容。DeepSeek不断在发布新版本,某些老版本的vLLM可能不支持最新权重,需要升级框架或者改用“官方指定的版本”。遇到报错时先去查版本的兼容说明,不要盲目重装。
5.2 微调阶段的效果不理想
微调后效果差,问题往往不在模型训练,而在数据或评估方式。
过拟合是最常见的问题。表现是训练集loss降到很低,但验证集loss很高,回答内容四平八稳但缺乏灵活性。解决办法是降低训练轮数、增大数据量、增加正则化。一般来说,LoRA几轮就可以学会,不需要跑十几个epoch。我见过有人把模型训练到完全记住了训练集,但任何问题都用训练集里的语气回答,非常僵硬。
学习率过大可能导致loss上下横跳,最终模型输出内容混乱。出现这种情况,把学习率降到原来的五分之一重试。反过来,学习率太小,loss下降缓慢,几轮下来效果提升不明显。
数据集里的噪声影响也很大。有时候标签本身有错,或者回答风格不统一,模型学到的就是一种平均风格,结果哪个都不像。我每次开始微调前,都会花大半天时间清洗数据,至少保证训练集、验证集没有格式冲突。
5.3 开发阶段的性能瓶颈
开发应用上线后,最常见的抱怨就是“太慢了”。这个慢可能体现在几个方面。
首字延迟高,也就是用户等很久模型才吐第一个字。这可能是因为系统提示词太多,模型还没开始生成前要做大量预填充计算。解决方法是精简系统提示词,或者使用前缀缓存技术,让相同前缀只算一次。
吞吐量上不去,同时处理不了多少请求。这通常卡在显存带宽和批处理策略上。vLLM的连续批处理已经很好了,但你可以检查一下max_num_seqs参数是否限制了并发,调高一点可能效果明显。
调用链路阻塞,比如RAG检索阶段太慢。向量数据库查询很快,但文本向量化如果串行执行会很慢,建议用批量接口或者异步方式处理。
还有一类问题是模型输出的字符串经常被截断,或者返回格式不符合预期。这不算性能问题,但很影响体验。解决办法是在请求参数里调高max_tokens,并且提示模型严格按要求格式输出。
5.4 我的几条个人心得
后续做项目过程中,我总结了几条经验随时拿来回看。
第一,版本管理比代码管理更重要。模型权重、训练配置、启动脚本、数据集的版本都要记清楚,每次改动前先备份。我经历过一次模型升级后效果断崖式下跌,就是因为微调数据被覆盖,想回滚都找不到原文件。
第二,永远保留一个“基线模型”。不管微调做得多好,你都需要一个未微调的模型作为对照,否则你不知道那些“变好”是微调的功劳,还是仅仅是提示词写得更详细了。
第三,自动评估是不可或缺的。上线前人工测试很有必要,但上线后每天跑一版自动评估,用真实的线上数据构建评估集,才能尽早发现问题。这个评估集要定期更新,因为用户的问题分布可能持续变化。
第四,不要只盯模型本身,应用架构设计可能更影响最终效果。同样的DeepSeek模型,配合好的RAG和提示词,能比裸模型表现好一个档次。优先优化提示词流程,再考虑微调,这条路线性价比最高。
最后再补充一个小技巧:定期查看模型加载的日志。很多问题在日志里会有蛛丝马迹,比如有些请求命中了显存缓存、有些请求超时重试,这些信息能帮你提前发现隐患。学会看懂日志,是你从“会用”走向“熟练”的标志。