简介:这份文档面向程序员、算法工程师及医疗信息化从业者,聚焦DeepSeek大模型在医疗场景中的私有化部署、数据训练与诊断辅助实战。资源为1个PDF文件,共24页,压缩包约1.77MB,内容涵盖医疗数据收集与预处理、私有化部署环境搭建、模型训练与调优、诊断辅助模型构建,并穿插真实案例分析与行业挑战应对。具体介绍了临床数据、医学影像数据、基因数据等多种医疗数据的处理方式,以及数据标注、质量评估、超参数调优等关键环节。目前已有110人学习下载,文档内容完整,目录、图表显示正常,可放心查阅。通过学习可掌握从软硬件配置、网络安全策略到模型集成与系统融合的完整方法,同时理解数据安全、隐私保护与合规性要求,适合希望快速上手DeepSeek医疗项目的中高级开发者。
1. 医院信息科找到你的时候,谈的不是AI而是数据安全
一个典型的医疗私有化部署需求长这样:医院内网有一套 HIS 系统,门诊医生每天要写大量病历,信息科想要引入大模型做诊断辅助,但唯一的硬性条件是患者数据不能出内网。于是任务落到程序员头上——把 DeepSeek 部署到内网 GPU 服务器,用脱敏病历做训练,再把这套能力嵌进医生的日常操作流。这个标题里的三个关键词其实是三段独立的工程:私有化部署解决「模型怎么在内网跑起来」,数据训练解决「通用模型怎么听懂医疗语境」,诊断辅助解决「模型输出怎么变成医生愿意用的工具」。适合读这篇文章的人,是有 Linux 和 Python 基础、调过 API 但没碰过本地推理的程序员。你不需要懂机器学习原理,但得做好面对一堆硬件、显存和玄学问题的准备。
2. 选型先于部署:医疗私有化场景下的硬件估算与模型裁剪
2.1 一张显卡跑不动671B:MoE结构决定了显存账单
很多第一次接触 DeepSeek 私有化的人,看到官方发布的模型权重是 671B 参数,第一反应是绝望。但你得先搞清楚 DeepSeek 用的是 MoE(Mixture of Experts)结构——总参数 671B,但每次推理只激活其中约 37B 参数。这意味着什么?推理吞吐量没那么吓人,但显存占用是按全部参数计算的,因为所有专家层的权重都得加载进显存。
实际估算公式很简单:显存 ≈ 参数量 × 每参数字节数 × 1.2(多出来的 20% 留给 KV cache 和激活值)。按这个算,671B 的 FP8 量化版本需要大约 670GB 显存,8 张 A100 80G 或 H800 才能勉强吃下。绝大多数医院的预算不会批这种配置。常见折中方案是选择 DeepSeek 蒸馏出来的 32B 或 14B 版本——这些版本用了同样的分词器和对话模板,在医疗指令微调上表现接近,但显存需求降了一个数量级。
| 模型规模 | 显存估算(BF16/FP16) | 量化后(INT4/FP8) | 推荐硬件 |
|---|---|---|---|
| 7B | 约 15GB | 约 6GB | 单卡 RTX 4090 / A30 |
| 14B | 约 28GB | 约 10GB | 单卡 A100 40G / 2×4090 |
| 32B | 约 64GB | 约 24GB | 2×A100 40G / 4×4090 |
| 671B(满血 MoE) | 约 1300GB | 约 670GB | 8×A100 80G / H800 集群 |
医疗行业客户的典型预算是 20 万到 50 万,对应下来就是 2 张 A100 40G 或者 4 张 4090。这个预算下 32B 量化版是性价比最优解。我一般不会一上来就推荐满血版,先把业务流跑通,再谈升级。
2.2 蒸馏版、量化版和原版:三个选择维度
DeepSeek 官方和社区发布的可用权重分三类:原版(V3/R1 系列)、蒸馏版(DeepSeek-R1-Distill-Qwen-32B 这类)、以及社区量化版(AWQ/GPTQ/FP8)。选哪个不只看显存,还要看你的下游任务是什么。
诊断辅助属于典型的「语言理解 + 结构化输出」任务,不是数学推理。原版 R1 在数学和代码上能力强,但对医疗场景没有额外加成,反而因为思维链太长导致响应慢。蒸馏版在中文指令跟随上表现稳定,且显存友好,是私有化部署的默认选择。社区量化版需要多留个心眼——有些量化版本在长文本医疗问答上会出现输出乱码或重复,我踩过 AWQ 4bit 在诊断建议里反复输出同一句话的坑。
经验做法是:优先用 BF16/FP16 的蒸馏版跑通全流程,确认为题后再考虑量化。如果显存实在不够,优先用 FP8 而不是 INT4,医疗文本的敏感性值得多花那点显存。
2.3 数据合规边界:私有化的真正门槛不在技术
私有化部署的第一驱动力永远是合规。医疗行业对患者数据有明确的本地化要求,数据不出院是红线。技术上的含义有三层:
第一,模型推理必须在医院内网完成,不能有任何外部 API 调用,包括模型服务本身的遥测都要关掉。第二,训练数据必须经过脱敏处理,这是比模型部署更早要做的环节。第三,内网环境和外网物理隔离时,模型权重文件的导入本身就是个工程问题——需要离线包、移动硬盘和严格的操作审批流。
我在需求评审阶段就会和客户确认这三件事,尤其是「训练数据从哪来、脱敏到什么程度」。有些医院说可以提供病历数据,但调出来后全是医生手写扫描件,OCR 都没做过,这直接决定了「数据训练」这一章节要花多大工作量。如果客户说「我们只有几百条数据,想训一个诊断模型」,这基本不可行,但也别直接拒绝——几百条数据做指令微调不够,但做提示词模板定制和少样本示例足够了。后面第 4 章会展开讲。
3. 用 vLLM 把 DeepSeek 跑进内网:最小部署命令与三个必调参数
3.1 模型权重获取:离线包导入与目录结构确认
进入部署实操前,先解决模型文件本身。内网机器一般没有外网访问权限,你需要在能联网的机器上下载权重,再拷进内网。ModelScope 在国内下载速度明显比 HuggingFace 快,命令行工具也简单。
# 在有外网的机器上执行,用 modelscope 下载蒸馏版模型 pip install modelscope modelscope download --model Qwen/DeepSeek-R1-Distill-Qwen-32B \ --local_dir /data/models/deepseek-32b # 下载完成后确认文件完整性 du -sh /data/models/deepseek-32b ls -lh /data/models/deepseek-32b | head -20下载完的目录里会包含config.json、model.safetensors.index.json和若干分片权重文件。拷进内网机器时注意两点:一是保持目录结构完整,vLLM 启动时会按--model参数读取整个目录;二是拷完后检查文件大小是否一致。
这里有个常见坑:很多人用 Ollama 或 LM Studio 习惯了,以为模型是一个独立文件,但 vLLM 需要的是完整目录。如果你拿到的是 GGUF 格式,vLLM 不支持,得换 llama.cpp 或 Ollama 方案。确认格式看config.json里有没有model_type字段即可。
3.2 vLLM 启动命令:三个必调参数
vLLM 是当前社区最常用的推理服务框架,吞吐量比原生 Transformers 高一个量级,而且自带 OpenAI 兼容的 API 接口。启动命令如下:
# 内网 GPU 服务器上执行,加载 32B 量化模型 cd /data/models vllm serve /data/models/deepseek-32b \ --tensor-parallel-size 4 \ --max-model-len 16384 \ --gpu-memory-utilization 0.92 \ --served-model-name deepseek-diag \ --host 0.0.0.0 \ --port 8000 \ --trust-remote-code启动日志里看到Starting vLLM server on http://0.0.0.0:8000说明服务已经起来了。接着用一个最小请求验证:
curl -s http://127.0.0.1:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "deepseek-diag", "messages": [ {"role": "system", "content": "你是诊断辅助助手,只根据患者症状给出可能的诊断方向,不做确定诊断。"}, {"role": "user", "content": "患者 58 岁男性,胸闷胸痛 2 小时,向左肩放射,伴大汗,既往高血压病史。"} ], "temperature": 0.3, "max_tokens": 512 }'3.3 参数含义与调参逻辑
--tensor-parallel-size是把模型切到几张卡上并行推理的参数。4 卡 40G 跑 32B 模型,切片数设为 4 是标准做法。设小了会显存溢出(OOM),设大了会在小模型上白增加通信开销。判断标准很简单:启动时观察 GPU 显存占用,每张卡吃到 90% 左右就是对的。
--max-model-len是上下文窗口上限,医疗场景里控制这个参数比想象中重要。诊断辅助的单轮输入是「主诉 + 现病史 + 既往史」,一般不会超过 4000 token。但多轮对话场景中,轮次多了累积起来很可观。这个值设太大会让显存浪费在预分配的 KV cache 上,设小了多轮对话会中断。医疗场景 16384 是一个起点值,后面按实际用量调。
--gpu-memory-utilization决定显存里给 KV cache 预留多少空间。0.92 意味着留 8% 余量给激活值和其他开销。调太高会导致并发稍高时 OOM,调太低会让并发能力大幅下降。如果你只有 2 张卡跑 32B 量化,这个值必须低于 0.90。
关于--host 0.0.0.0,内网部署时一定要这样绑,否则业务系统只能在本机访问。但绑了之后要注意网络安全组权限,只开放给内网业务网段,不要把 8000 端口暴露到非受信网络。
3.4 服务接入:deepseek-harness 与内网业务对接
模型服务跑起来只是第一步。医院的业务系统(HIS、电子病历系统)不太会直接调/v1/chat/completions接口,它们需要一个更薄的封装层。社区里常见的做法是部署一个叫 deepseek-harness 的网关服务,它负责把内部 API 格式转换成 OpenAI 兼容格式,再转发给 vLLM。
harness 这类工具本质是消息格式转换器加会话管理器。为什么需要它?因为 vLLM 本身是无状态推理引擎,不维护历史对话;而诊断辅助必须以多轮对话形态存在。我在第 6 章会详细讲会话管理,这里先说明一点:harness 不只是可选件,而是私有化部署链路里负责「有状态」的关键一环。它一般和 vLLM 跑在同一台内网服务器上,通过 localhost 调用,不占额外 GPU。
# 一个典型的 harness 启动示例(不同实现启动方式有差异,但都是这种套路) docker run -d \ --name deepseek-harness \ -p 8080:8080 \ -e LLM_BASE_URL=http://127.0.0.1:8000 \ -e SESSION_TIMEOUT=1800 \ deepseek-harness:latest接入后,业务系统只面对一个http://内网IP:8080的标准化接口,模型换版本、换推理后端都不需要改业务代码。这就是私有化部署里常说的「门面模式」——你的模型服务是黑匣子,harness 是唯一入口。
4. 医疗数据训练:从病历清洗到 LoRA 微调的一条完整链路
4.1 医疗数据三条红线:去标识化、质控、拒答样本
模型在内网跑通之后,你用通用 DeepSeek 试问几个医疗问题,大概率能答得像个科普文章。但一放到真实病历上,它就露馅了:科室术语不认、诊断逻辑跳跃、建议里出现「建议咨询专业医生」这种废话。这就是为什么要做数据训练。
医疗数据训练的起点是病历语料。常见做法是从医院的信息系统里导出结构化病历字段(主诉、现病史、诊断、治疗方案),然后按诊断辅助的任务形态构造成对话样本。但数据处理阶段有三个红线,少做一条后面都会翻车:
第一,去标识化。患者姓名、身份证号、住院号、手机号、具体住址必须全部替换成占位符。这不是可选项,是法律要求,也是医院授权数据集的前提。第二,质量筛选。不是所有病历都是有效训练语料——长度低于 20 字的记录、纯符号记录、OCR 乱码记录要过滤掉。你以为是数据量越大越好,实际上 1 万条干净样本远胜过 100 万条垃圾。第三,保留拒答样本。医疗场景里「这个症状我暂时无法判断,请尽快就诊」这类回答必须进入训练集。模型如果学成「什么都能答」的江湖郎中,那才是真正的生产事故。
4.2 用 Python 写一个病历清洗脚本:核心逻辑与敏感信息替换
import re import json # 敏感信息模式:各字段按医院数据情况自行补全 patterns = { "name": r"[\u4e00-\u9fa5]{2,4}(?=,|,|。|;|;)", "phone": r"1[3-9]\d{9}", "id_card": r"\d{17}[\dXx]", "hospital_no": r"(?:住院号|就诊号)[::]?\d{5,}", } def desensitize(text: str) -> str: text = re.sub(patterns["phone"], "[电话]", text) text = re.sub(patterns["id_card"], "[身份证]", text) text = re.sub(patterns["hospital_no"], "[住院号]", text) # 姓名替换需要结合前缀和上下文,简单正则容易误伤 text = re.sub(patterns["name"], "[患者]", text) return text def filter_valid_record(rec: dict) -> bool: # 过滤掉过短记录和纯符号记录 combined = rec.get("chief_complaint", "") + rec.get("present_illness", "") if len(combined) < 20: return False if len(re.findall(r"[^\u4e00-\u9fa5a-zA-Z0-9]", combined)) / len(combined) > 0.3: return False return True # 处理入口:按行读取导出的 JSONL 病历 with open("raw_records.jsonl", "r", encoding="utf-8") as f_in, \ open("clean_records.jsonl", "w", encoding="utf-8") as f_out: for line in f_in: rec = json.loads(line) if not filter_valid_record(rec): continue rec["chief_complaint"] = desensitize(rec["chief_complaint"]) rec["present_illness"] = desensitize(rec["present_illness"]) rec["diagnosis"] = desensitize(rec["diagnosis"]) f_out.write(json.dumps(rec, ensure_ascii=False) + "\n")这段脚本是一个通用骨架。patterns里的正则按你拿到的病历格式调整——不同医院导出的字段名不同,有些是chief_complaint,有些是主诉,建议先导 100 条做字段探查再写正则。filter_valid_record后面的判断条件是用来过滤 OCR 乱码的,比例阈值 0.3 是我试过比较稳的值。另外要提醒一句:简单的姓名正则误伤率很高,「王医生建议复查」会被替换成「[患者]医生建议复查」。如果数据量小(几千条),我一般建议用人工抽检 + 正则两级配合,不要全自动跑完不管。这一步提供了模型的清洗逻辑,但需要自己按数据集字段调整。
4.3 构造指令数据:系统提示词、输入输出与训练格式
清洗完的原始病历要变成模型能学的对话样本。标准做法是构造「指令-回答」对。医疗诊断辅助场景里,指令就是主诉和病史拼接,回答就是诊断方向和处置建议。
典型的一条训练样本长这样:
{ "messages": [ { "role": "system", "content": "你是三甲医院临床诊断辅助助手。你只能根据患者主诉和病史给出可能的诊断方向,输出格式为【可能诊断】【鉴别诊断】【建议检查】【处置建议】。如果信息不足,明确说需要补充问诊。不要给出确定性诊断结论。" }, { "role": "user", "content": "主诉:胸闷伴气促3天。现病史:患者3天前无明显诱因出现胸闷,活动后加重,伴夜间阵发性呼吸困难。既往史:高血压病史10年,未规律服药。" }, { "role": "assistant", "content": "【可能诊断】1. 慢性心力衰竭(左心衰竭)2. 高血压性心脏病\n【鉴别诊断】与 COPD 急性加重、肺栓塞鉴别\n【建议检查】心电图、胸部X线、BNP或NT-proBNP、超声心动图\n【处置建议】建议心内科就诊,完善上述检查,暂不建议自行调整降压药。" } ] }这个格式直接对应 HuggingFace 的chat_template结构,也是主流的指令微调工具能直接消费的格式。构造训练集时注意:系统提示词必须在所有样本里保持一致,不要一文一换。模型会学到「系统提示词是模板,不需要关注」的规律,如果你在训练集里替换成各种角色设定,模型会变得飘忽。
数据量参考:500 到 2000 条高质量的诊断对话就能在 32B 模型上做出肉眼可见的效果提升。这里的核心逻辑不是让模型学会诊断知识,而是让模型学会「用医院科室的术语、按医生的格式输出」。诊断知识已经在预训练阶段掌握了,你要做的是把它校准到医疗场景的引用方式上。
4.4 LoRA 微调实战:LLaMA-Factory 与关键超参数
微调用什么工具?社区里最常见的两条路是 LLaMA-Factory 和 SWIFT。LLaMA-Factory 对新手更友好,配置文件清晰,显存控制也好。
# LLaMA-Factory 启动 LoRA 微调(以 32B 模型为例) cd LLaMA-Factory CUDA_VISIBLE_DEVICES=0,1,2,3 python src/train.py \ --model_name_or_path /data/models/deepseek-32b \ --dataset medical_diag_train \ --dataset_dir ./data \ --template qwen \ --finetuning_type lora \ --lora_rank 16 \ --lora_alpha 32 \ --output_dir ./output/deepseek-32b-lora \ --num_train_epochs 3 \ --learning_rate 2e-4 \ --per_device_train_batch_size 4 \ --gradient_accumulation_steps 4 \ --logging_steps 10 \ --save_steps 100 \ --bf16 True \ --max_length 4096几个参数说明:
--lora_rank 16是 LoRA 低秩矩阵的维度。rank 越高,模型能学到的「新知识」越多,但风险也越大——rank 32 以上容易在小数据集上过拟合。16 到 24 是医疗场景比较稳的区间。--lora_alpha 32是缩放系数,一般设为 rank 的 2 倍,控制新参数对原模型的影响强度。--learning_rate 2e-4是 LoRA 微调的标准学习率,全量微调一般用 1e-5 以下,LoRA 因为参数少可以更大。--num_train_epochs 3在千条数据集上属于起点,数据量少于 500 条就降到 2,超过 5000 条可以加到 4。过拟合的典型表现是训练集 loss 持续下降但验证集回答质量变差。
训练产出的是一个 LoRA 适配器目录(几十到几百 MB),不是完整模型。部署时用 vLLM 加载需要把适配器合并回原模型权重,或者用支持适配器动态加载的推理框架。合并命令在 LLaMA-Factory 里一条指令搞定:
python src/export_model.py \ --model_name_or_path /data/models/deepseek-32b \ --adapter_name_or_path ./output/deepseek-32b-lora \ --template qwen \ --finetuning_type lora \ --export_dir /data/models/deepseek-32b-medical合并后的deepseek-32b-medical才是最终部署到 vLLM 的模型。这一步产生的坑特别多——合并后模型对话格式错乱、重复输出、甚至完全不可用,都属于常见现象,多半是--template参数和模型原对话模板不匹配。DeepSeek 系列用的对话模板需要在 LLaMA-Factory 里确认,qwen模板适用于 DeepSeek 蒸馏的 Qwen 系列,但你如果从官方 DeepSeek V3 微调则要配套对应的模板。这个点后面避坑章节还会再讲。
5. 私有化部署避坑实录:我从诊断辅助项目里捡回的四个教训
5.1 微调后模型把「感冒」诊断成「病毒性心肌炎」:数据抽样偏置的问题
现象:用 1200 条病历训练完,模型对常见病的回答变得奇怪。普通感冒样本被模型判定为「需要住院排查心肌炎」,而真实病历里这个诊断比例根本没那么高。
原因:训练集构建时按「病历号连续段」抽取,恰好抽到了某一周的心内科重症病历为主,而 ICU 病历里感冒和心肌炎的鉴别是高频内容。模型学到的是这个子分布而不是真实诊断分布。
解决:重新按诊断类别做分层采样。先统计全部训练数据的诊断标签分布,再按比例从每个类别里抽取样本,确保类别不平衡控制在合理范围。我当时重采后,常见病和危重症的比例从 1:3 拉回 3:1,模型输出就正常了。
经验:训练数据不是随机抽样就行的,必须按标签分布检查。这一步省不得,否则后面微调出来了模型,还得回头返工数据清洗。
5.2 量化模型输出连续重复同一句话:AWQ 4bit 在医疗长文本上不稳定
现象:INT4 量化版在短问题(「头疼怎么办」)上回答正常,但输入超过 2000 字的病史描述时,模型突然输出重复的处置建议,叠了三四遍同一句话。
原因:INT4 量化把权重压缩到 4bit,在长上下文和长生成场景下累积误差会变大,模型陷入重复循环。诊断辅助的输入往往很长(病史 + 检查结果 + 既往史),刚好踩中这个弱点。
解决:换成 FP8 量化或直接上 BF16。在 32B 模型上,FP8 相比 BF16 显存只省 20%,但稳定性提升一个量级。如果你只有 2 张卡又必须用 INT4,就在提示词里加上「不要重复相同内容」,但这是临时缓解手段,治标不治本。
5.3 多轮对话第二轮开始模型「失忆」:vLLM 无状态导致会话断裂
现象:第一轮问「患者有高血压史吗」,模型答了。第二轮问「那降压药还用不用」,模型答「我不知道患者是否有高血压」。医生直接判定系统不可用。
原因:vLLM 的/v1/chat/completions接口本身是无状态的——它只处理你传进来的messages数组,不保存任何上下文。前端或业务系统没做消息历史拼接,只传了本轮问题,模型自然「失忆」。
解决:在 harness 层做会话管理。最简单的方式是用 Redis 存 session:以session_id为 key,每次请求都把历史消息取出来,拼上当前问题,一起发给 vLLM。同时设置轮次上限——医疗场景建议最多保留 8 轮历史,超过后把早轮信息压缩成摘要再拼入。这里还关联一个搜索热词里的问题「怎么让新对话承接上一个对话」,在私有化架构下答案很清楚:这不是模型能力问题,是消息组装问题,由 harness 层解决。
5.4 模型加载成功但对话模板错乱:微调合并后的 template 不匹配
现象:合并 LoRA 适配器后部署到 vLLM,启动正常,但一问问题,返回的是训练格式里的「【可能诊断】」标签,而且整段回答是乱序的,像是把训练样本直接吐出来了。
原因:LoRA 微调时--template设置成qwen,但 DeepSeek 蒸馏版自带更长的系统提示词模板,合并后 vLLM 加载时又把它识别成deepseek模板,两边不一致导致输入格式错乱。
解决:合并模型前,先用transformers的apply_chat_template方法跑通一条推理测试,确认输出格式正确再部署。如果合并后仍然错乱,直接用--template deepseek重新微调一次,或者手动修改合并模型的tokenizer_config.json里的chat_template字段对齐 DeepSeek 官方模板。
5.5 训练集里没有拒答样本:所有问题都「自信满满」地回答
现象:模型对「这是不是癌症」这类问题,给出明确判断。甚至输入「患者胸口疼」这种症状极模糊的记录,也自信满满打出一串诊断加上治疗方案。医疗场景里这不可接受。
原因:训练数据全部来自确诊病历,模型学到的模式是「输入主诉 → 直接给结论」。没有样本教它「信息不足应该拒绝回答」。
解决:在训练集里加入 10% 到 15% 的拒答样本。构造方法很简单:把真实病历截断一半,标注成「信息不足,请补充 XX 检查结果」。这个比例不用太多,但保证模型在这类样本上有稳定的输出行为。
6. 把诊断辅助做得像样:回归验证集、结构化输出与多轮会话管理的三个落地技巧
模型部署完、微调完、避坑避完,离「医生愿意用」还差最后一步:把模型输出变成可验证、可控制、可追溯的产物。这是我做过的项目里真正区分「能用」和「好用」的三件事。
第一件事是建回归测试集。从训练数据中预留 200 条不参与训练的病历,再让科室医生手工标定期望回答里的三个关键点:诊断方向是否正确、建议检查是否合理、是否包含需要警惕的危险信号。每次微调后先跑这批回归样本,比对输出内容和基线的差异。模型输出是生成式的,不能直接断言相等,但你可以让医生按 0-5 打分,低于 3 分的样本进错误列表反查原因。我第一次跑回归测试时发现 30% 的样本有诊断方向偏移,查下来是训练数据里「糖尿病」和「糖尿病肾病」标签没分开导致的。
第二件事是约束输出为 JSON 结构。诊断辅助不能只是「生成一段话」,要让模型输出一个可被业务系统解析的结构:
{ "diagnosis_list": ["慢性心力衰竭(待排除)"], "confidence": 0.72, "examination_suggestions": ["BNP", "超声心动图"], "danger_signals": ["夜间阵发性呼吸困难"], "advice": "建议心内科就诊,完善检查前避免剧烈活动" }在提示词里给出这个 JSON 结构模板,并用json模式约束 vLLM 输出(OpenAI 兼容接口支持response_format参数),然后在 harness 层做解析失败兜底。医生界面看到的不再是一段话,而是结构化列表,每条建议带置信度和危险信号标识,这才能真正嵌入到 HIS 系统的医嘱流程里。
第三件事是把多轮会话的轮次管理做严格:单患者会话最多 8 轮,超过后自动把前几轮的诊断线索压缩成一段摘要替换入上下文。诊断辅助的多轮对话不像闲聊,医生问三轮基本就把关键信息问完了,后面的轮次价值很低,但 token 占用很高。压缩策略是我在性能优化里最喜欢做的部分——用 DeepSeek 自己来总结关键诊断信息,而不是直接丢弃早期内容。
回到开头说的:很多团队把私有化部署理解成「把模型装到内网服务器」,做完第一步就宣布项目完成。实际经验是 vLLM 跑起来大概只完成了三分之一,数据训练和输出控制才是真正拉开差距的地方。我最早做的第一版诊断辅助翻车就是因为只部署不训练,模型给出的「帮助」全是教科书复读,医生用了两天就退回手写病历。后来老老实实走完数据清洗、微调、回归验证这条路,才拿到了科室的持续使用。希望帮到你。
本文还有配套的精品资源,点击获取