“DeepSeek Harness 部署到服务器上,同事们玩嗨了”——这个标题严格说不是我的原话,是运维老张在周五下午的组会上说的。当时我们刚把内网的大模型服务从各自笔记本跑实验,切换到统一部署在公司机房一台 GPU 服务器上的 DeepSeek Harness,连着两个星期,运营、研发、产品三个部门十几个同事天天在上面跑对话、写摘要、生成测试数据。今天这篇就把我这次从零部署到上线、再到被同事“玩出花”的完整过程拆开讲清楚,重点说环境准备、安装链路、权限设计和踩坑点,给想在服务器上搭一套团队可用的 DeepSeek Harness 的人做个直接能抄的参考。
1. 把场景理清楚:服务器部署 DeepSeek Harness 到底解决什么问题
1.1 团队现状与部署动机
在动手之前,我们必须先回答一个问题:为什么非要把 Harness 放到服务器上,而不是像很多人一开始那样,在本地电脑上装一个桌面端自己玩?
我们团队当时的情况比较典型。研发用自己的 4090 工作站跑 DeepSeek 模型做代码补全实验,运营同事电脑配置一般,只能在网页端用各家 API,产品经理要批量总结用户反馈,只能一条条复制粘贴。结果就是:好一点的显卡被研发独占,其他同事用不上;API 用量分散在个人账号里,月底账单一堆,报销麻烦;关键对话记录和 Prompt 模板都存在个人浏览器里,换台电脑就没了。
这种情况本质上不是缺一个模型客户端,而是缺一个“团队共享的大模型工作台”。DeepSeek Harness 恰恰是这样一个东西——你可以把它理解成一个围绕 DeepSeek 模型的统一入口,它不只是聊天窗口,而是把模型调用、提示词管理、会话记录、多用户访问都包在一个服务里。部署到服务器之后,所有人都通过浏览器访问同一个服务,算力统一调度,数据留在内网,这才是上服务器的核心价值。
1.2 大模型共享服务的两种路线对比
真正开始做方案时,我们内部讨论过两条路线,这个选择直接决定后续所有工作,值得详细说一下。
第一条路线是“API 网关路线”。也就是自己写一个后端服务,封装 DeepSeek 的 API Key,做鉴权、限流、日志,然后前端接一个开源聊天界面。这条路线的优点是轻量,一台 2C4G 的小服务器就能跑,开发工作量集中在写转发层。缺点也很明显:所有请求还是走公网 API,数据出内网这个问题绕不开;而且每次 DeepSeek 官方接口升级参数,你都得跟着改适配代码。
第二条路线就是“Harness 托管路线”。把 DeepSeek Harness 整个部署在内网服务器上,模型权重直接落在服务器本地磁盘,或者通过内部网关转发到模型服务。所有对话数据、提示词模板、会话历史全部留在内网。同事访问的是一个完整的应用,而非一个裸 API。缺点是需要一台配置不错的 GPU 服务器,部署和调优周期比写个网关长。
我们最终选了第二条路线。原因很简单:我们很多业务数据敏感,不允许出内网;另外团队需要一个可持续积累的提示词库和会话知识库,这个用 Harness 管理比自研省太多事。
2. 服务器环境准备:这些坑我在正式部署前都踩过
2.1 硬件配置与操作系统选型
先说结论,我们最终用的是双路 Intel Silver 4314(32 核 64 线程)、256GB DDR4 ECC 内存、一张 NVIDIA RTX 4090 24GB 显卡、2TB NVMe 系统盘 + 4TB 数据盘的组合。这个配置对 DeepSeek Harness 来说属于“中配偏上”。
为什么是这个配置?关键在显存。DeepSeek 系列模型有不同的规模,如果是 7B 量级的量化模型,24GB 显存够用;如果是 32B 甚至 67B 的中大模型,24GB 只能跑 4bit 量化,速度还会受影响。我们最常用的 DeepSeek-R1-Distill-Qwen-14B 量化后大概占用 11GB 显存,4090 跑起来比较从容,同时还能留一部分给其它服务。内存方面,模型加载到内存做缓存、多人并发时的上下文管理,都很吃内存,256GB 看起来奢侈,但后面跑起多个模型实例后一点也不多。
操作系统我强烈建议用 Ubuntu Server 22.04 LTS。这不是因为它比 CentOS 强多少,而是生态问题:PyTorch、CUDA、Docker 的新版本,官方文档几乎都是先在 Ubuntu 上测试,很多大模型相关的坑在 Ubuntu 上最少。CentOS 7 这种老系统不是不能用,但你需要自己编译一堆依赖,纯属给自己找事。
2.2 Docker 环境与网络策略
Harness 部署我只推荐用 Docker 方式,不推荐裸机直接跑。原因有四个:第一,隔离性,模型服务、Web 服务、数据库各跑各的容器,互不影响;第二,可回滚,升级版本出问题直接回退镜像,不用在服务器上折腾依赖;第三,多实例,后面要给不同部门开独立实例,Docker 复制一套配置就行;第四,迁移方便,换服务器直接导出镜像,比重新部署快一个数量级。
Docker 安装本身不难,但国内网络环境有几个坑要提前处理。一是 Docker Hub 镜像拉取慢,我们当时拉一个基础镜像等了好几分钟,后来配置了镜像加速器才解决。二是 Ubuntu 自带的 iptables 和 Docker 默认网段可能冲突,如果你服务器上有别的服务占用了 172.17.x.x 网段,容器网络会起不来,需要在/etc/docker/daemon.json里显式指定"bip": "10.10.0.1/24"这样的独立网段。
网络策略上,我建议部署阶段先不要开公网访问,就在内网 VLAN 里访问,等确认没有明显安全漏洞后再决定是否暴露。服务器防火墙只开三个口:SSH 端口(建议改掉默认 22)、Harness Web 端口(我们用的是 8080)、HTTPS 端口(443)。其他一律关闭。
2.3 基础镜像与依赖版本注意
这里有个血泪教训:DeepSeek Harness 对 Python 版本比较敏感。我们第一次部署时,服务器上默认 Python 是 3.8,结果装依赖阶段一堆包编译报错,折腾了两天才发现官方要求 Python 3.10+。
建议在一开始就固定好版本组合,避免“装到一半发现版本不兼容”的尴尬:
| 组件 | 推荐版本 | 备注 |
|---|---|---|
| Ubuntu Server | 22.04 LTS | 生态兼容性最好 |
| Docker | 24.0.x+ | 需要支持 Compose V2 |
| CUDA | 12.1+ | 对应 PyTorch 2.1+ |
| Python | 3.10+ | 低于 3.10 会有一堆编译问题 |
| Node.js | 18.x+ | 前端构建需要 |
| Git | 2.30+ | 拉取项目仓库 |
还有一个容易忽略的点:磁盘空间。模型文件动辄十几个 GB,加上 Docker 镜像和日志,4TB 的数据盘我们用了不到半年就剩一半了。建议给/var/lib/docker单独挂一块大容量数据盘,避免系统盘被撑爆。
3. DeepSeek Harness 安装与配置的完整链路
3.1 拉取项目与安装方式选择
环境准备好之后,正式开始安装。DeepSeek Harness 的安装方式主要有三种:源码部署、Docker 部署、一键脚本部署。我们实际采用 Docker Compose 方式,这里把完整链路写出来。
源码部署的好处是灵活,可以改前端代码,但坏处是依赖管理噩梦。一键脚本适合单机快速体验,但不适合生产环境长期使用。Docker Compose 介于两者之间,配置清晰、升级方便、依赖都被官方镜像打包好了,是团队使用场景下最稳的选择。
操作步骤如下:
# 1. 拉取项目代码 cd /opt git clone https://github.com/deepseek-ai/DeepSeek-Harness.git cd DeepSeek-Harness # 2. 查看目录结构 ls -la # 正常情况下应该看到 docker-compose.yml、.env.example、config/ 等文件 # 3. 复制环境变量模板并修改 cp .env.example .env vim .env这里.env文件是配置的核心,我逐个字段解释:
# 服务端口 HARNESS_PORT=8080 # 数据存储目录(注意改成数据盘) DATA_DIR=/data/harness # 模型配置 MODEL_LOAD_MODE=local # 本地加载模型 MODEL_PATH=/data/models # 模型权重存放目录 # 安全配置 ACCESS_TOKEN=your-secure-token # 服务访问令牌3.2 模型接入方式配置:本地权重 vs API
这一步是 Harness 部署的灵魂:模型到底是本地加载,还是走 API?
我们最开始被“本地部署”这个词误导了,以为必须把 DeepSeek 官方的大模型完整下载下来。实际上,DeepSeek Harness 支持两种模式,各有适用场景。
本地加载模式适用于:数据完全不能出内网、需要离线使用、对延迟敏感的场景。你需要先把模型权重下载到服务器本地。以我们用的 DeepSeek-R1-Distill-Qwen-14B 为例,从 HuggingFace 或 ModelScope 下载,量化后大约 9-10GB。下载命令:
# 使用 modelscope 下载(国内速度快很多) pip install modelscope modelscope download --model deepseek-ai/DeepSeek-R1-Distill-Qwen-14B-GGUF --local_dir /data/models/deepseek-r1-distill-qwen-14b下载完模型后,需要在 Harness 的配置文件中指定模型路径,并配置推理后端。这里有一个关键决策:使用 vLLM 还是 llama.cpp。
我们一开始用的是 llama.cpp,因为它在单卡、量化场景下部署最简单,CPU 也能跑,配置量小。但用了两周后发现并发能力不足,四个人同时提问,后面的人要排队很久。后来切换到 vLLM,并发吞吐提升非常明显,同一个 14B 模型在 vLLM 下的并发处理能力至少是 llama.cpp 的三到四倍。
vLLM 启动推理服务的参考配置:
docker run -d \ --name vllm-server \ --gpus all \ -v /data/models:/models \ -p 8000:8000 \ vllm/vllm-openai:latest \ --model /models/deepseek-r1-distill-qwen-14b \ --quantization awq \ --tensor-parallel-size 1 \ --max-model-len 8192 \ --gpu-memory-utilization 0.85API 接入模式则适用于:本地没有好显卡、但可以走公网 API 的场景。在 Harness 的配置里填上 DeepSeek 开放平台的 API Key,模型请求会自动转发到云端。这个模式部署简单,但数据不出内网这条就满足不了了。
我们的最终方案是“本地为主、API 兜底”:日常用本地 vLLM 推理,当本地服务负载过高时,通过 Harness 的 fallback 配置自动切到 API。这个组合在稳定性和成本之间找到了平衡。
3.3 网络端口、反向代理与 HTTPS 配置
Harness 服务默认绑定 8080 端口,但直接让同事用 IP:8080 访问有两个问题:一是 Chrome 等浏览器对非标准端口有时会有安全提示;二是后续要加统一登录认证,直接用端口裸奔不好搞。
我们配置了 Nginx 反向代理,把 443 端口的 HTTPS 请求转发到内网 8080。配置要点:
server { listen 443 ssl; server_name harness.company.internal; ssl_certificate /etc/nginx/ssl/harness.crt; ssl_certificate_key /etc/nginx/ssl/harness.key; client_max_body_size 20m; location / { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # WebSocket 支持,Harness 有实时流式输出 proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 600s; proxy_send_timeout 600s; } }这段配置里最容易被忽略的是 WebSocket 升级头。Harness 的对话流式输出依赖 WebSocket,如果不加Upgrade和Connection头,前端会一直转圈加载不出内容。另一处是proxy_read_timeout,模型推理可能超过默认的 60 秒,尤其是多人排队的时候,设大一点避免 504 错误。
证书我们用的是内网自建 CA,给每台同事电脑装了根证书,Chrome 就不会报不安全警告。如果你们有公网域名,直接用 Let's Encrypt 更方便,但那样等于把 Harness 暴露到公网,安全策略要重新评估。
4. 多玩家入场:让同事们用得顺手的权限与交互设计
4.1 多用户权限与会话隔离
服务跑起来之后,最迫切的问题就是:怎么让十几个人同时用,但各自的数据互不干扰?
DeepSeek Harness 支持多用户体系,但默认配置下很多人会忽略。我们实际启用并配置了基于用户的权限控制,核心思路是:部门隔离 + 项目共享。
具体做法是在配置文件中开启认证模式:
auth: enabled: true mode: ldap # 也可以选 local 或 oauth2 ldap_server: ldap://openldap.internal:389 default_role: viewer admin_group: "cn=ai-admin,ou=groups,dc=internal" user_group: "cn=ai-users,ou=groups,dc=internal"我们接入了公司已有的 OpenLDAP,这样同事不用单独注册账号,用企业账号密码就能登录。这里有个体验细节:不少人希望“扫码登录”或者“企业微信登录”,如果你们公司有 OAuth2 的统一认证,优先用那个,LDAP 虽然简单,但对普通同事来说输入账号密码还是有点门槛。
权限角色我们划分了三档:
- admins:能管理配置、查看所有会话、升级模型
- users:能使用对话、创建和管理自己的提示词模板、查看共享模板
- viewers:只能对话,不能保存修改配置
会话隔离方面,Harness 默认每个用户只能看到自己的会话记录,但我们开了“项目共享会话”功能,把市场部的同事拉到一个项目组里,他们可以共享某些模型的会话上下文,方便协作调 Prompt。这个功能在跨部门合作时非常有用。
4.2 并发控制与负载均衡
“同事玩嗨了”的另一面就是:挤爆了。上线第三天下午,运营同事集体用 Harness 批量生成文案,直接把我们 vLLM 服务的并发队列打满,一个请求要等五分钟才能出结果。这时候才意识到,没有并发控制的多用户服务就是灾难。
解决分两层:外层是 Harness 应用级限流,内层是 vLLM 的并发参数调优。
Harness 配置里:
rate_limit: enabled: true strategy: token_bucket requests_per_minute: 30 burst_size: 10 per_user: true这个配置给每个用户每分钟最多 30 个请求,突发 10 个,避免有人用脚本批量刷。下面给每个部门设置了不同的配额,研发部门因为要做代码生成实验,配额给到 60 RPM;其他部门 30 RPM。
vLLM 侧的调优也很关键。核心参数--max-num-seqs决定了同时处理的序列数,默认 256,但我们要限制同时处理的数量,避免显存溢出。我们最终设置为 64,--max-model-len调成 8192,因为同事大部分用法是短对话,上下文太长反而浪费显存。
经过这轮调优,高峰时段也能保证每个请求 3 秒内开始响应,体感好多了。
4.3 让同事从 Web 端和 IDE 插件都能访问
部署完成之后,同事们反馈最好用的入口是 Web 端,但研发那边更希望在 IDE 里直接调用。
我们在 Harness 里启用了 OpenAI 兼容接口。这个功能很关键,因为现在几乎所有 IDE 插件(Continue、Cline、GitHub Copilot 的替代方案等)都支持自定义 OpenAI API Endpoint。地址填https://harness.company.internal/v1,模型名填我们在 Harness 里配置的模型名,插件就能直接用了。
具体配置示例(以 Continue 插件为例):
{ "models": [ { "title": "DeepSeek R1 14B 内网", "provider": "openai", "model": "deepseek-r1-distill-qwen-14b", "apiBase": "https://harness.company.internal/v1", "apiKey": "harness-api-key" } ] }这里有个需要注意的坑:Harness 的 OpenAI 兼容接口要求在请求头里带上有效的 API Key,不能为空。我们为研发同事每人签发了一个独立的“机器访问 Token”,这样出了问题也可以单独回收,不影响到其他同事的 Web 会话。
WebSocket 和 SSE 两种流式输出协议在 IDE 插件中表现不同,实测 Continue 插件用 SSE 更稳定,Cline 用 WebSocket 更流畅,这个需要在插件各自的配置里微调,没有统一答案。
5. 上线后的真实反馈与常见问题排查
5.1 同事们最爱的几个玩法
部署上线三周,我观察到一个很有意思的现象:同事们的使用方式远超我的预期,很多是我们部署时根本没想到的。
第一个爆款用法是“周报生成器”。运营同事在 Harness 里建了一套提示词模板,让模型根据本周的工作记录自动生成周报。这个模板在 Harness 的可视化 Prompt 编辑里调出来的效果特别好,因为支持结构化输出,还能自动带上历史周报的格式。结果整个运营中心都来问怎么用,我们只好在 Harness 里做了一个共享模板库,把这些常用 Prompt 固化下来。
第二个用法是“会议纪要结构化”。产品经理把会议录音转的文字贴进去,让模型输出决议、待办、责任人、时间节点。这个用法对上下文要求高,但 14B 模型在中文理解上表现超出预期,只要输入格式规范,输出结构几乎不用改。
第三个用法是“测试数据批量生成”。研发同事用 Harness 的批量模式,让模型生成一批带边界条件的 Mock 数据。以前手写 50 条测试数据要一上午,现在几分钟搞定,而且模型生成的数据比手工写的更自然,覆盖更全面。
5.2 高频问题的根因和解决方法
上线后遇到不少问题,挑几个高频且有共性的说一下排查思路。
问题一:部分同事页面一直转圈,刷新也没用。排查链路:先看浏览器控制台报错,是 WebSocket 连接失败;再查 Nginx 配置,发现proxy_read_timeout是默认 60 秒,模型推理时间超过就断了;调整超时时间后解决。这个问题的本质是 WebSocket 长连接和代理超时的冲突。
问题二:并发高峰期服务质量下降严重。之前提到过,最开始 vLLM 参数没调好,队列堆积。彻底解决是在 Harness 的监控面板里加了报警规则,当平均响应延迟超过 30 秒就通知运维,同时把 vLLM 的--max-num-seqs从默认值降下来,牺牲一点吞吐换稳定性。
问题三:有的同事上传文档后,Harness 提示格式不支持。这是 Harness 对文档解析的格式限制。解决方案有两个:一是让同事优先上传 Markdown 或纯文本格式;二是我们在 Harness 后面挂了文件转换服务,把 PDF、Word 统一转成纯文本再喂给模型。选第二个方案是因为同事用 Word 和 PDF 的频率太高,不自动转换根本没法用。
问题四:模型回答时好时差。这个不算 bug,但被同事反复提。排查下来发现,很多人直接在默认会话里提问,没有任何系统提示词设定。后来我们在 Harness 里创建了不同场景的独立“工作区”,比如“代码助手模式”和“写作助手模式”,不同工作区绑定不同的系统提示词和温度参数,效果稳定很多。
5.3 资源监控与定期维护
服务器上跑了个全员在用的服务,最怕的就是半夜挂掉没人知道。我们做了三件事保证稳定:
第一,部署了监控告警。用 Prometheus + Alertmanager 监控 CPU、内存、GPU 显存使用率、API 错误率、平均延迟五个核心指标。规则设成:GPU 显存使用率超过 90% 持续 5 分钟,或错误率超过 1% 持续 10 分钟,就告警到企业微信群。
第二,建立了模型版本升级流程。DeepSeek 官方会更新模型权重和 Harness 版本,我们不能看到新版就直接部署。现在的流程是:先在测试服务器上跑一周基准测试,比较新旧版本在团队常用任务上的输出质量和响应速度,确认没问题再切生产。比如之前从 R1 蒸馏版升级到更新版本时,发现代码生成场景输出明显变好,但长文档摘要变差,最后通过 Harness 的多模型路由配置,让不同场景走不同模型版本。
第三,定期清理会话和数据。同事在 Harness 里聊了大量业务数据,这些数据有价值但也有存储成本。我们设置了一个定时任务,每周末备份一次会话数据库,历史会话保留 90 天,超过的自动归档到冷存储。提示词模板库这类高价值资产则永久保留。
最后分享一个实际运维中的小技巧
整个部署过程中,让我觉得最值回票价的一个决定,就是把 Harness 的配置文件和数据目录做了标准化备份。我先用一个脚本在每天凌晨自动备份/opt/DeepSeek-Harness下面的.env、docker-compose.yml、config/整个目录,以及/data/harness下面的会话数据库,备份到另一台存储服务器。这个看起来不起眼的习惯,后来在一次磁盘故障恢复中立了大功——新服务器从装系统到恢复服务,只花了 45 分钟,同事几乎没有感知到宕机。
所以我的建议是:别光顾着把服务跑起来,备份策略、监控告警、升级回滚预案这三件事,一定要在正式让同事使用之前就做好。毕竟大模型服务的特性决定了它一旦在一个团队里流行开,就没有人能接受它突然挂掉这件事。