简介面向医疗AI工程师、医院信息化人员及深度学习初学者这份PDF文档聚焦DeepSeek在医院场景中的落地与CT影像识别模型微调。文档共27页从医疗影像分析的定义、技术手段和应用场景讲起详细介绍DeepSeek的技术特点及医院级部署所需的硬件、网络与系统集成步骤针对CT影像数据讲解格式转换、归一化、噪声去除等预处理方法并说明数据收集与标注要点。模型部分解析CNN、RNN、GAN及ResNet、U-Net等典型架构并围绕迁移学习给出预训练模型选择、冻结部分层、损失函数与优化器定义、训练循环及模型评估的代码级微调流程。此外还覆盖学习率调整、正则化、Dropout、批量归一化、早停与模型融合等优化策略以及准确率、精确率、召回率、F1值、ROC/AUC等评估指标的选择依据与评估方法。通过三甲医院肺部疾病识别和社区医院肝脏CT筛查两个案例完整展示从数据准备到效果评估的真实项目路径。资源为单个PDF文件共27页压缩包1.76MB目录清晰、图文正常已有136人学习下载适合希望系统掌握DeepSeek医疗影像部署与微调实战的读者。文档结构完整从环境准备到模型优化环环相扣既可作为教学参考也可作为项目落地手册。1. 医疗影像分析里的医院级 DeepSeek 部署与 CT 模型微调先看清边界再动手医疗影像分析领域里医院级 DeepSeek 部署与 CT 影像识别模型微调其实是同一件事的两端一端让大模型在院内 GPU 上跑起来另一端让视觉模型在 CT 切片上找到病灶。很多团队第一次启动时会默认把 70B 大模型塞进机房跑完才意识到医院场景的瓶颈不是模型聪明不聪明而是内网环境、显存预算、患者数据出不去以及夜里没人值守。经验做法是先做小DeepSeek 部署从 7B/14B 开始CT 模型用公开预训练权重微调再把两个服务串成一条报告流水线。这个标题背后要解决的问题就是——让影像科拿到自动报告草稿让工程师拿到能复现的落地路径。适合有 Python 和 Linux 基础、但没做过院内 AI 交付的人。2. 医院级 DeepSeek 部署内网 GPU 选型与 Ollama 最小落地2.1 先选对模型7B/14B/32B 在院内显卡上的成本与收益医院本地部署大模型面对的第一个问题不是部署工具而是部署多大的模型。DeepSeek 的本地化生态里常见选择是 DeepSeek-R1 蒸馏到 7B、14B、32B 的版本。你不需要在机房塞一台八卡 A100大部分医院的 IT 环境里一张 24GB 显存的 RTX 4090 或 A5000 就能支撑 14B 模型的日常推理。这个结论背后是量化和显存的关系。常见做法是拉取 Q4_K_M 或 Q8 量化后的模型文件7B 大约占 6GB 显存14B 大约占 10GB 到 14GB32B 量化后也要 20GB 以上。显存之外还要留出上下文和 KV cache 的空间所以 24GB 的卡跑 32B 会很紧张14B 反而可以从容地留下并发余量。医院内网通常还要跑 CT 识别模型GPU 不是只给一个大模型用的显存预算得同时算两笔账。模型规格量化后显存单卡建议适合场景DeepSeek-R1 蒸馏 7B约 6GB12-16GB术语归一化、关键词抽取、快速摘要DeepSeek-R1 蒸馏 14B约 10-14GB24GB影像报告草稿、结构化输出DeepSeek-R1 蒸馏 32B约 20-26GB48GB 或双卡复杂病历生成、多轮修订选型有一个容易被忽略的判断医院场景里14B 的“够用”才是生产力。部署之后要接 HIS、要做访问控制、要留日志、要处理 DICOM 和 PACS这些工程成本不会因为模型变大而减少反而会因为显存不足被无限放大。如果是为了中文报告生成DeepSeek 的 Qwen 系蒸馏版本通常比 Llama 系更适合这也是很多人纠结“是不是需要依托千问模型然后进行微调”的原因。默认让 14B 先跑起来比一步到位上大模型更保险。2.2 用 Ollama 把 DeepSeek 拉起来systemd 与监听地址调整原型验证阶段我直接用 Ollama。它把模型下载、加载、服务暴露封装成一条命令是最快的本地部署 DeepSeek 路径。前提是机器上有 NVIDIA 驱动操作系统用 Ubuntu 22.04 最常见。# 安装 Ollama curl -fsSL https://ollama.com/install.sh | sh # 拉取 14B 量化模型首次会下载约 9GB 权重建议内网先预下载 ollama pull deepseek-r1:14b # 本地验证一句中文问答 ollama run deepseek-r1:14b 右下肺见类圆形小结节直径约 6mm请写一句CT报告描述第一步是安装脚本第二步下载模型第三步进入交互式对话。为什么不用 Docker 安装在内网环境容器镜像仓库访问容易受限直接用官方脚本让 Ollama 以 systemd 服务方式安装模型文件放在~/.ollama/models后面做离线分发也方便。如果单位要求严格可以先把模型包下载到移动硬盘再拷进机房这是常见的离线部署做法。装好之后要改监听地址否则只有本机能访问。用 systemd override 文件设置环境变量mkdir -p /etc/systemd/system/ollama.service.d cat /etc/systemd/system/ollama.service.d/override.conf EOF [Service] EnvironmentOLLAMA_HOST0.0.0.0 EnvironmentOLLAMA_KEEP_ALIVE5m EnvironmentOLLAMA_NUM_PARALLEL2 EOF systemctl daemon-reload systemctl restart ollama这里三个参数的含义分别是OLLAMA_HOST0.0.0.0让服务可以被局域网内其他应用调用注意防火墙只放开内网网段OLLAMA_KEEP_ALIVE5m控制模型在显存中的驻留时间避免频繁加载模型造成的延迟OLLAMA_NUM_PARALLEL2让同一个模型允许两个请求并发。医院场景里并发不是越大越好显存占满了会影响 CT 模型训练建议从 2 开始观察显存占用再调。2.3 OpenAI 兼容 API 接入Python 调用与 vLLM 高并发切换Ollama 提供/v1接口协议和 OpenAI 兼容所以 DeepSeek API 如何调用这个问题在医院内网可以直接套用 openai 客户端。下面这段 Python 是接入最小示例from openai import OpenAI client OpenAI( base_urlhttp://192.168.10.20:11434/v1, # 内网Ollama服务地址 api_keylocal, # Ollama 不校验 key但字段要保留 ) resp client.chat.completions.create( modeldeepseek-r1:14b, messages[ {role: system, content: 你是一名影像科医生输出必须简洁、严谨只用中文。}, {role: user, content: 请解释右上肺磨玻璃影的常见原因。}, ], temperature0.2, max_tokens512, ) print(resp.choices[0].message.content)逻辑上就是构造一个 OpenAI client把base_url指向内网服务其他参数和云端一致。temperature0.2是医疗文本生成上的常用低温度因为报告需要低随机性温度越高越容易“编”。max_tokens512控制单次输出长度影像报告草稿一般不会超过这个量。当你从原型走向高并发比如影像科一次性批量处理几十个序列Ollama 的前端并发模型就不够用了。常见做法是把 DeepSeek 换成 vLLM它提供更成熟的连续批处理和 PagedAttention能把单张 A5000 的吞吐提高好几倍。切换时只需要把 Python 代码里的base_url指向 vLLM 的/v1地址模型名称改成对应部署名。也有团队用 Codex 这类智能体工具接入本地 DeepSeek 做接口调试原理同样是改base_url日常测试非常方便。先 Ollama 后 vLLM是成本最低的一条递进路径。3. CT 影像识别模型微调DICOM 预处理、YOLO 训练与 LoRA 文本兜底3.1 预处理第一步DICOM 窗口化转 PNG标注转 YOLOCT 识别模型微调的第一步永远不是搭网络而是把医院导出的 DICOM 文件变成模型能吃的 PNG。DICOM 里存的不是一张普通照片而是 12 位或 16 位的 CT 值直接转 PNG 会变成一张黑乎乎或者惨白的图必须在转换时做窗宽窗位处理。import pydicom import numpy as np from PIL import Image ds pydicom.dcmread(slice.dcm) # 拿到真实的 CT 值乘 RescaleSlope加 RescaleIntercept hu ds.pixel_array.astype(np.float32) * float(ds.RescaleSlope) float(ds.RescaleIntercept) # 肺窗窗宽 1500 Hu窗位 -600 Hu width, center 1500, -600 lower center - width / 2 upper center width / 2 img np.clip((hu - lower) / (upper - lower), 0, 1) img (img * 255).astype(np.uint8) Image.fromarray(img).save(slice.png)这段代码先把像素值乘上RescaleSlope再加上RescaleIntercept得到真实 CT 值然后按肺窗做线性映射。window_width1500, window_center-600是看肺结节和磨玻璃影最常用的参数如果同时要做纵隔窗分析改成400, 40再生成一路输入。pixel_array可能已经是负数直接转uint8会溢出所以要先转float32。标注转换同样容易踩坑。PACS 医生标注往往画在 DICOM 坐标下导出后可能是 XML 或 JSON而 YOLO 需要每张图一个 txt每行是“类别 x_center y_center width height”。转换时保持原始图像分辨率用归一化坐标顺序别填错x_center 是相对宽度不是绝对像素。这块逻辑看起来简单却是后面训练能否收敛的成败点。3.2 开始微调之前想清楚冻结层、学习率与图像尺寸影像识别模型微调已经有成熟路线目前最常见的是拿 Ultralytics YOLO 系列当底座。为什么选 YOLO 而不是自己搭 CNN医院场景要的是快速交付、可解释的检测框和低标注成本YOLO 预训练权重对纹理、边缘的通用特征迁移能力足够配合少量医学数据微调就能到实用效果。这里用肺结节检测做演示不代表临床诊断结论。# ct_nodule.yaml path: ./ct_nodule train: images/train val: images/val nc: 1 names: [nodule]训练主线用一行命令跑起来from ultralytics import YOLO model YOLO(yolov8s.pt) # 加载 COCO 预训练权重 model.train( datact_nodule.yaml, epochs100, lr01e-4, freeze10, imgsz640, batch8, device0, close_mosaic10, )参数选择有讲究。lr01e-4比自然图像默认低一个数量级因为医学数据集通常只有几百到几千张学习率太大权重会立刻被少数样本带偏freeze10表示冻结前 10 层 backbone让提取边缘纹理的参数保持预训练状态只训练后面检测头这是样本少时常用的防过拟合手段imgsz640是显存和感受野的平衡点想抓更小的结节可以试imgsz1024但显存占用几乎翻倍close_mosaic10表示最后 10 个 epoch 关闭马赛克增强避免增强分布和真实分布偏离导致 mAP 抖动。微调并不只限于检测模型。如果要做影像分类或图文检索还可以考虑 CLIP 这类图像语言预训练模型做微调CLIP 的视觉编码器对医学概念不是天然对齐的需要在院内数据上做对比学习。不过在 CT 影像的实际交付里目标检测仍然是首选因为病灶定位、尺寸测量都依赖框直接决定了报告里能不能写“位置”和“大小”。先把 YOLO 的框跑出来再谈多模态检索会踏实得多。3.3 DeepSeek 要不要微调先试 LLaMA-Factory 的 LoRA 路线很多人看到“DeepSeek 部署与 CT 影像识别模型微调”这个标题会误会成“微调 DeepSeek 去做影像分析”。实际上图像识别任务交给视觉模型DeepSeek 承担的是报告生成和结构化。如果只是想让 DeepSeek 写出符合本院报告习惯的语句优先试的是提示词工程而不是微调。只有当提示词怎么调都达不到要求比如报告模板有严格的科室缩写、术语表、结论句式才需要微调语言模型。医院内网数据敏感多数情况不允许把病历文本送到云端训练本地微调用 LLaMA-Factory 是常见选择。它同时支持 Qwen、DeepSeek 蒸馏模型SFT 阶段做 LoRA 可以大幅降低显存需求。典型命令llamafactory-cli train \ --model_name_or_path Qwen2.5-7B-Instruct \ --stage sft \ --finetuning_type lora \ --dataset radiology_sft.json \ --output_dir outputs/radiology_lora \ --num_train_epochs 3 \ --learning_rate 2e-4 \ --per_device_train_batch_size 2 \ --gradient_accumulation_steps 4 \ --lora_rank 16 \ --max_length 2048这里的lora_rank16是性价比很高的默认值不是越大越好学习率2e-4对 LoRA 是比较温和的步长max_length2048足够覆盖一段影像所见加结论。数据集格式是instruction/input/output三字段建议把医院脱敏报告整理成这种结构。微调完导出 LoRA 权重再合并回原模型之后的调用方式不变。工程上很多人跑完一遍才理解“是不是需要依托千问模型然后微调”这句话答案通常是不用一开始就微调但 LLaMA-Factory 已经把这个过程做到半天能出结果值得留作后备方案。4. 串联 DeepSeek 和 CT 模型检测结果如何变成结构化报告4.1 先定工作流CT 切片检测在前大模型生成在后把 DeepSeek 和 CT 识别模型放在同一台内网服务器上不只是各自起一个服务而是要定好数据流向。影像科的流程是CT 扫描生成一个序列几百张轴位切片→ DICOM 传到 PACS → 分析服务从 PACS 拉图 → 预处理转 PNG → YOLO 逐张检测 → 把阳性切片和检测框聚合 → 生成自然语言描述 → DeepSeek 输出报告草稿 → 医生在 RIS 系统里修改确认。关键判断是不要让大模型直接读像素。语言模型不是视觉模型即便多模态版本能看图对 CT 切片的解读也很难被医院质控接受。更可靠的做法是让 YOLO 负责“看到”让 DeepSeek 负责“写成一段人话”。这种解耦还带来一个工程好处——视觉模型可以频繁迭代换成更强的检测权重报告层的提示词和代码不需要重写。工作流设计里还有一条容易被忽略每个序列几百张切片大部分是阴性直接全部塞给大模型既浪费也算不准。建议先让 YOLO 跑完所有切片只把置信度超过阈值的发现写进中间 JSON阴性序列直接走“未见明显异常”模板。这样 DeepSeek 每次推理只处理几十个候选框延迟和成本都可控。4.2 中间桥接代码把 JSON 发现拼成提示词并调用本地 DeepSeek桥接代码的任务是把检测结果变成文本再送给 DeepSeek。下面是一段可以在实际环境直接改的 Python 示例import json from openai import OpenAI # 假设 YOLO 推理结果已经写成 findings.json with open(findings.json, r, encodingutf-8) as f: findings json.load(f) prompt f 请根据以下肺部CT自动检测结果生成一份简短的报告草稿。 要求 1. 按“影像所见”和“结论”两段输出。 2. 不得增加检测结果之外的信息。 3. 只使用中文医学术语。 检测结果 {json.dumps(findings, ensure_asciiFalse, indent2)} client OpenAI( base_urlhttp://127.0.0.1:11434/v1, api_keylocal, ) resp client.chat.completions.create( modeldeepseek-r1:14b, messages[{role: user, content: prompt}], temperature0.2, max_tokens512, ) report resp.choices[0].message.content print(report)这段代码做了三件事从检测结果文件读 JSON按 prompt 模板组装上下文再用 OpenAI 兼容接口调用本地 DeepSeek。temperature0.2和前面同理是医疗文本生成里的保守参数提示词里那句“不得增加检测结果之外的信息”很重要它抑制模型自由发挥是减少幻觉的第一道闸。很多刚接手的团队会纠结要不要上复杂的 agent 编排平台。实际上如果医院环境能接受把检测脚本包成 HTTP 服务再用 Dify 这类工具做本地部署的工作流会省掉大量前端活。流程大概是Dify 里配一个“自定义工具”指向 YOLO 服务的 HTTP 接口再配一个 LLM 节点调用 Ollama 或 vLLM 的端点不需要写一长串胶水代码。Dify 工作流建议用在非实时场景实时阅片还是走脚本加队列更稳。4.3 性能账一个序列多少张图并发多少请求才不卡医院上线前要回答一个实际问题一台机器能不能应付一天的检查量。先估单例耗时一个常规胸部 CT 序列约 200 到 400 张轴位切片YOLOv8s 在 4090 上推理一张 512×512 切片大约 20 到 30 毫秒整个序列检测只需 10 秒上下DeepSeek 14B 生成 300 到 500 token 的报告草稿在这台机器上约 10 到 20 秒。单个病例从拉图到出报告草稿可以压在 60 秒以内。容量规划按影像科高峰时段算比如一天 300 个胸部 CT都集中在上午 4 小时平均每秒不到 0.03 个序列单卡配置明显够用。真正会打满 GPU 的不是业务量而是批量回溯比如科研团队要一次性重跑过去一个月的影像。这时要用异步队列不能把 PACS 拉图和模型推理放在同一个同步请求里。常见并发参数如下环节工具并发设计PACS 拉取 DICOMorthanc / pynetdicom限速 3 并发YOLO 检测PyTorch/TensorRT动态 batch 8DeepSeek 推理vLLM 或 Ollama流式输出串行限制报告回写RIS 接口失败重试队列PACS 拉取最容易被低估DICOM 文件平均几百 KB 到几 MB一个序列几百张图直接多线程拉会把 PACS 打挂。限速 3 并发看起来保守但能保证影像科正常浏览不受影响。YOLO 检测用动态 batch 把多张切片凑成一批吞吐提升比单张循环高得多。DeepSeek 推理则要控制并发语言模型的显存占用随并发非线性增长14B 模型 2 并发已经是很多 24G 显卡的舒适上限。5. 避坑指南医院级部署与微调常见的五个翻车点医院级最大的特点是没有试错空间部署翻车往往要等到影像科老师坐在工作站前才暴露。我把这几年踩过最深的五个坑写下来每条都是血泪经验按现象、原因、解决三步讲清楚。5.1 长报告生成一半就停Ollama 上下文窗口没调现象用 Ollama 调 DeepSeek 生成 CT 报告内容超过两三百字就戛然而止后端没有报错输出被硬生生截断。原因Ollama 默认num_ctx只有 2048也就是模型能看到的上下文加生成的 token 总长只有 2048输入提示词一长留给生成的长度就所剩无几。医院场景很容易触礁因为 CT 检测结果转成 JSON 后可能就有上千 token。解决调用时显式传num_ctx。Ollama 原生接口里设置options.num_ctxOpenAI 兼容接口也可以透传扩展字段。一般 14B 模型建议设819232B 建议4096同时留意显存占用会随上下文长度上升。5.2 转完 PNG 全黑或全白窗宽窗位和像素溢出现象把 CT 的 DICOM 转成 PNG 后整张图要么黑到看不见组织要么白到只有骨头模型训练和人工标注都无法使用。原因DICOM 像素值不是 0 到 255 的灰度值。它可能是带符号的 16 位整数范围从 -1024 到 3000 以上直接np.uint8(pixel_array)会把中间所有值截断成 0 或 255另外很多人没乘RescaleSlope导致窗宽窗位换算完全无效。解决先转float32乘斜率加截距再做窗口映射。肺窗用1500/-600纵隔窗用400/40最后裁到 0 到 255。这步做完再拿几张典型病例人工看一眼任何一张全黑全白都不能进入数据集。5.3 标注框跑偏DICOM 方向坐标没做仿射变换现象微调完成后模型推理出的检测框坐标写回 PACS医生发现框的位置和病灶差了几个厘米把正常组织圈了进来。原因DICOM 有ImageOrientationPatient和ImagePositionPatient表示空间方向但 PNG 就是矩阵像素。医院导出时如果经过了旋转或翻转像素坐标和空间坐标之间不是简单线性关系。标注时医生软件上看到的位置和训练时 PNG 的位置对不上。解决导出 PNG 和标注时锁定同一个坐标系最省力气的方法是直接在预处理后的 PNG 上重新标注而不是在 PACS 上标注再转换。如果需要用已有 DICOM 标注就要解析方向余弦矩阵做仿射变换这是典型的黑匣子地带。我一般会写变换断言跑通训练集后随机抽查 20 张 GT 框叠加图人工确认边界没有整体偏移。5.4 微调 OOM 和 NaNimgsz、Batch 和 AMP 三件套现象训练刚开始没几步torch.cuda.OutOfMemoryError就来了改小 batch 好了一会又出现 loss 为 NaN整个训练进程白跑。原因OOM 是因为imgsz和 batch 是平方级乘显存的CT 图本身像素大很多人习惯性用 1024 以上NaN 在医学影像里常出现在 AMP 混合精度下低对比度、小目标区域在 FP16 下梯度过小演变成数值不稳定。解决先设imgsz640、batch4跑通一次训练再逐步加大。训练前关掉混合精度Ultralytics 里用ampFalse。还有一招后悔药是梯度裁剪YOLO 里可以设置nbs64稳定大 batch 的梯度。医学影像训练最忌讳“看运气”每次训练前记下环境版本和这几个参数翻车才有排查入口。5.5 DeepSeek 一本正经编造病灶提示词和温度没约束现象DeepSeek 生成的报告草稿读起来很像回事结论里写“右下肺见 6mm 磨玻璃结节建议随访”但 YOLO 检测结果里根本没有这个框。原因大模型天然会补全缺失信息特别是 prompt 没有明确“只基于检测结果”时它会根据训练语料里的常见病例模式编一个合理说法。temperature 默认 0.7 太高也会放大这种随机性。解决第一道约束在提示词里写死“不得增加检测结果之外的信息”第二道把temperature调到 0.2 以下第三道加一个轻量规则校验把报告里的病灶描述和检测 JSON 做关键词匹配发现报告出现了 JSON 里没有的解剖位置就标记为“疑似幻觉”。这三层下来基本能把胡说压到可接受范围比单独指望模型“变聪明”可靠得多。6. 上线前最后一步用最小闭环脚本证明整套链路可用部署告一段落最重要的一块拼图是在真实数据之外先跑通最小闭环。我有一个长期维护的冒烟脚本作用是用一张 DICOM 切片验证五件事预处理能出图、YOLO 能出框、DeepSeek 能出报告、报告里有关键词、整个流程在预算时间内完成。# 1. 转换 python tools/convert_dicom.py --input sample_slice.dcm --output /tmp/slice.png # 2. 检测 python tools/detect.py --weights ct_nodule.pt --source /tmp/slice.png --json /tmp/findings.json # 3. 报告 python tools/generate_report.py --findings /tmp/findings.json \ --api http://127.0.0.1:11434/v1 --output /tmp/report.md每个脚本要单独返回非零退出码。最后一步用 grep 检查报告里是否出现和findings.json对应的关键词比如检测到 nodule 就检查“结节”两个字是否在报告里。这个脚本可以做成每日巡检也可以写成 CI 任务挂在机房内网。医院部署和算法比赛有一个很大差别算法比赛看指标医院交付看“换一台机器能不能复现”。我每次换服务器第一件事不是调参而是把这套最小闭环跑到绿如果换了个干净的容器环境还能一次通过说明依赖、路径、服务地址都写清楚了才放心让影像科接入。否则等医生工作站上手再发现链路断点真数据、真账号、真流程搅在一起排查成本会高十倍。把闭环脚本和版本号一起存档也算是给自己留一份后悔药。这个方向踩过很多次坑之后我慢慢发现最值钱的经验不是某条命令而是把它们固化成一个能反复验证的基线。希望帮到你。本文还有配套的精品资源点击获取