DeepSeek 相关项目落地时,团队常见的架构问题不是“能不能跑模型”,而是如何在本地部署、海外 GPU 算力、API 兼容服务和业务系统之间建立稳定链路。尤其是当业务团队在国内,GPU 资源在海外,模型文件又需要从不同仓库下载时,网络架构会直接影响部署效率、推理延迟和故障排查。
本文只讨论合规前提下的工程架构:如何区分官方 API、本地推理和远程算力调度;如何用 vLLM 或 Ollama 暴露服务;如何设计跨地区网络、队列、缓存和监控。文中的模型名、接口格式和命令以官方文档为准,具体生产参数应结合自己的模型版本和硬件环境测试。
一、区分三种DeepSeek使用方式
DeepSeek 相关应用大致有三种路线:
| 路线 | 适合场景 | 网络重点 |
|---|---|---|
| 官方 API | 快速接入、低运维成本 | API连接、限流、错误处理 |
| 本地部署 | 数据不出环境、离线推理、研发测试 | 模型下载、GPU内存、内网调用 |
| 海外算力调度 | 本地业务 + 海外 GPU 资源 | 跨境链路、任务队列、结果回传 |
DeepSeek 官方 API 文档说明,其 API 使用兼容 OpenAI/Anthropic 的格式;OpenAI 格式的 base_url 为 https://api.deepseek.com,Anthropic 格式的 base_url 为 https://api.deepseek.com/anthropic。官方文档当前列出的模型包括 deepseek-v4-flash、deepseek-v4-pro,同时说明 deepseek-chat 和 deepseek-reasoner 会在 2026-07-24 15:59 UTC 弃用。
这意味着生产代码里不建议长期写死旧模型名。模型名、思考模式、超时和重试参数都应该进入配置中心或环境变量,由运维和研发共同管理。
如果需要私有化推理,就要转向模型权重、推理框架和 GPU 资源。vLLM 官方文档提供了 OpenAI-compatible server 能力,Ollama 官方生态则更适合本地开发、轻量测试和单机服务。
二、推荐架构:本地业务和GPU推理解耦
如果业务系统在国内,GPU 资源在海外,不建议让业务代码直接连接每台 GPU 机器。更合理的做法是引入任务网关和推理服务层:
业务系统
-> LLM Gateway
-> 任务队列
-> 海外GPU推理集群
-> 结果存储 / 回调服务
-> 业务系统读取结果
这个架构的核心是解耦:
- 业务系统不直接感知具体 GPU 节点;
- 推理集群可以独立扩容、重启和升级模型;
- 跨境链路只承载标准化请求和结果,不传输无关数据;
- 故障发生时,可以判断是业务、队列、网络还是推理节点问题。
对于实时聊天类任务,可以走同步 API;对于批量摘要、文档分析、代码审查等长任务,更适合走异步队列。
三、DeepSeek官方API调用示例
官方文档给出的思路是使用 OpenAI SDK 并设置 DeepSeek base_url。下面是一个更适合工程排查的最小封装:
import os
import time
from dataclasses import dataclass
from openai import APIConnectionError, APIStatusError, APITimeoutError, OpenAI
@dataclass(frozen=True)
class DeepSeekApiConfig:
api_key: str
base_url: str = "https://api.deepseek.com"
model: str = "deepseek-v4-pro"
timeout: float = 45.0
max_retries: int = 2
def load_config() -> DeepSeekApiConfig:
return DeepSeekApiConfig(
api_key=os.environ["DEEPSEEK_API_KEY"],
base_url=os.getenv("DEEPSEEK_BASE_URL", "https://api.deepseek.com"),
model=os.getenv("DEEPSEEK_MODEL", "deepseek-v4-pro"),
timeout=float(os.getenv("DEEPSEEK_TIMEOUT", "45")),
max_retries=int(os.getenv("DEEPSEEK_MAX_RETRIES", "2")),
)
def build_client(config: DeepSeekApiConfig) -> OpenAI:
return OpenAI(
api_key=config.api_key,
base_url=config.base_url,
timeout=config.timeout,
max_retries=config.max_retries,
)
def chat_once(prompt: str) -> str:
config = load_config()
client = build_client(config)
started = time.perf_counter()
try:
response = client.chat.completions.create(
model=config.model,
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": prompt},
],
stream=False,
)
cost_ms = round((time.perf_counter() - started) * 1000, 1)
print({"provider": "deepseek", "model": config.model, "cost_ms": cost_ms})
return response.choices[0].message.content or ""
except APITimeoutError as exc:
raise RuntimeError(f"deepseek timeout: {exc}") from exc
except APIConnectionError as exc:
raise RuntimeError(f"deepseek connection error: {exc}") from exc
except APIStatusError as exc:
raise RuntimeError(f"deepseek status={exc.status_code}: {exc.response.text[:300]}") from exc
if __name__ == "__main__":
print(chat_once("用三句话解释什么是 KV Cache"))
注意:模型名、thinking 参数、reasoning effort、弃用计划要以 DeepSeek 官方文档为准。不要把这些参数写死在业务函数里,建议统一放在 Adapter 层或配置中心。
四、Router设计:不同任务走不同推理路径
DeepSeek 项目里,最不建议的做法是所有请求都打到同一个模型、同一条链路、同一组 GPU 服务。不同任务的时延、成本、上下文长度和稳定性要求完全不同。
| 任务类型 | 推荐路径 | 原因 |
|---|---|---|
| 实时问答 | 官方 API 或低延迟本地服务 | 对响应速度更敏感 |
| 批量摘要 | 队列 + 本地/海外 GPU | 可以异步处理,重视吞吐 |
| 文档分析 | 异步任务 + 对象存储 | 输入大,运行时间长 |
| 代码解释 | 高质量模型 + 较长 timeout | 输出质量比秒级响应更重要 |
| 内部知识库问答 | 本地部署 + RAG 检索 | 便于权限和数据边界管理 |
| 大批量离线任务 | 海外 GPU 集群 + 批处理队列 | 更适合弹性算力调度 |
可以用一个轻量 Router 表达这个思路:
from dataclasses import dataclass
from typing import Literal
TaskType = Literal["chat", "batch_summary", "doc_analysis", "code_review"]
Target = Literal["deepseek_api", "local_vllm", "remote_gpu"]
@dataclass(frozen=True)
class InferencePolicy:
target: Target
timeout_seconds: int
queue_required: bool
def choose_policy(task_type: TaskType, input_tokens: int) -> InferencePolicy:
if task_type == "chat" and input_tokens < 8000:
return InferencePolicy("deepseek_api", timeout_seconds=45, queue_required=False)
if task_type in {"batch_summary", "doc_analysis"}:
return InferencePolicy("remote_gpu", timeout_seconds=300, queue_required=True)
if task_type == "code_review":
return InferencePolicy("local_vllm", timeout_seconds=180, queue_required=True)
return InferencePolicy("deepseek_api", timeout_seconds=60, queue_required=False)
这段代码不是完整调度系统,但能体现关键原则:模型选择、网络链路和任务策略不应该藏在业务代码深处,而应该由 Router 或 Gateway 统一控制。
五、本地部署:vLLM与Ollama的角色不同
本地或私有化部署时,常见选择包括 vLLM、Ollama、llama.cpp、SGLang 等。这里重点讨论两类:
| 工具 | 更适合 |
|---|---|
| vLLM | 服务化、高并发、OpenAI-compatible 接口 |
| Ollama | 本地开发、单机测试、轻量模型管理 |
| llama.cpp | 边缘设备、轻量模型、本地实验 |
| Kubernetes + vLLM | 多节点、弹性扩容、滚动升级 |
vLLM 官方 Quickstart 文档包含 offline inference 和 online serving,并提供 OpenAI-compatible server 相关能力。对于企业服务化部署,vLLM 更适合作为推理服务层,通过统一 API 被网关调用。
Ollama 则更适合开发机或小团队内部测试。它的价值是降低本地试验成本,但不能直接替代生产级网关、任务队列、权限控制和监控体系。
六、vLLM服务化示例
vLLM 当前文档推荐使用 vllm serve 暴露在线服务。示例命令可以写成:
vllm serve deepseek-ai/DeepSeek-R1-Distill-Qwen-7B \
--host 0.0.0.0 \
--port 8000
模型名称、显存需求、并行参数、量化方式都要以实际模型和硬件为准。不要在没有压测的情况下把示例命令直接作为生产配置。
业务侧可以通过 OpenAI SDK 调用自建服务:
import os
from openai import OpenAI
client = OpenAI(
api_key=os.getenv("LOCAL_LLM_API_KEY", "EMPTY"),
base_url=os.environ["LOCAL_LLM_BASE_URL"],
timeout=60.0,
)
response = client.chat.completions.create(
model=os.environ["LOCAL_LLM_MODEL"],
messages=[{"role": "user", "content": "生成一份接口压测计划"}],
)
print(response.choices[0].message.content)
这里的关键不是命令本身,而是接口边界:业务只访问 LLM Gateway 或 vLLM API,不直接管理模型进程。模型升级、GPU 扩容、实例重启都应在推理服务层完成。
还要注意三点:
- 自建服务的
base_url只应暴露给内部网关或可信应用; - 本地模型的上下文长度、输出格式、工具调用能力不一定与官方 API 完全一致;
- 模型升级时必须保留旧版本回滚路径,不能只覆盖当前服务。
七、海外算力调度:跨境链路不要传输无关数据
当 GPU 在海外,业务在本地时,最容易犯的错误是把所有上下文、日志、原始文件都跨地区传输。这样不仅慢,也不利于安全和合规。
建议采用标准化链路:
业务系统
-> 国内 LLM Gateway
-> 跨境网络链路
-> 海外 Inference Gateway
-> GPU Worker Pool
-> Object Storage / Result Store
这里要遵循三条原则:
- 请求最小化:只传推理必要内容,文件先清洗和摘要;
- 结果结构化:返回 JSON、文本或对象存储地址,不频繁回传大文件;
- 链路固定化:业务系统到推理网关使用稳定的跨境网络链路,避免临时网络影响任务。
如果团队需要长期调度海外 GPU,跨境网络链路应作为基础设施统一规划。IPdodo 这类跨境网络服务适合放在“业务系统与海外算力节点之间的稳定访问环境”中评估,重点关注链路稳定性、出口管理、故障排查和团队可管理性。
这种架构的好处是,业务系统只需要访问一个稳定入口,海外 GPU 节点可以独立扩缩容,大文件可以先放对象存储,网关也可以统一做鉴权、限流、日志和熔断。
八、任务队列:把长推理任务异步化
DeepSeek 本地部署和海外算力调度中,长任务不建议走同步 HTTP 长连接。更稳妥的设计是 job 模式:
POST /llm-jobs
-> 返回 job_id
GET /llm-jobs/{job_id}
-> queued / running / succeeded / failed
GET /llm-jobs/{job_id}/result
-> 返回文本、JSON 或对象存储地址
队列里至少要记录:
| 字段 | 作用 |
|---|---|
| job_id | 全链路追踪 |
| task_type | 决定路由和模型 |
| input_size | 判断是否需要摘要或分片 |
| target | deepseek_api / local_vllm / remote_gpu |
| retry_count | 控制失败重试 |
| timeout_at | 避免任务无限运行 |
| status | queued、running、succeeded、failed |
异步队列还有一个好处:跨境链路短时波动不会直接把用户请求打断。任务可以在后端重试、切换节点或返回明确失败原因。
九、模型下载与缓存:不要让每台机器重复下载
DeepSeek 或其他大模型部署时,模型文件通常很大。生产环境不建议每台 GPU 节点都临时从外部仓库下载。
推荐流程:
模型仓库
-> 下载机 / 缓存节点
-> 校验 hash / revision
-> 内部分发
-> GPU 节点加载
-> 服务健康检查
需要记录:
- 模型名称;
- revision 或 commit id;
- 文件 hash;
- 下载时间;
- 分发节点;
- 加载参数;
- 启动日志;
- 加载失败日志;
- 回滚版本。
这样做的好处是可复现。模型服务出现异常时,可以明确知道当前运行的是哪个版本,而不是只看到一个模糊的模型名称。
十、监控指标:同时看网络、队列、GPU和业务
DeepSeek 本地部署 + 海外算力调度至少要监控四类指标。
网络层:
| 指标 | 意义 |
|---|---|
| tcp_connect_ms | 跨境连接是否稳定 |
| p95_latency_ms | 高峰时段体验 |
| timeout_count | 链路或服务超时 |
| transfer_bytes | 上下行数据量 |
| retry_count | 重试是否异常增多 |
推理层:
| 指标 | 意义 |
|---|---|
| queue_wait_ms | 任务排队时间 |
| time_to_first_token | 首 token 延迟 |
| tokens_per_second | 生成吞吐 |
| gpu_memory_used | GPU显存压力 |
| model_load_seconds | 模型加载时间 |
| error_rate | 服务异常比例 |
队列层:
| 指标 | 意义 |
|---|---|
| queue_depth | 是否积压 |
| queue_wait_ms | 任务等待时间 |
| job_timeout_count | 长任务是否过多 |
| retry_exhausted_count | 重试后仍失败的任务数 |
业务层:
| 指标 | 意义 |
|---|---|
| task_success_rate | 业务成功率 |
| avg_cost_per_task | 成本趋势 |
| fallback_count | 降级次数 |
| manual_retry_count | 人工重试次数 |
只有同时看这些指标,才能判断慢是网络慢、队列慢、GPU 忙,还是模型服务本身慢。
十一、上线前检查清单
- 官方 API、vLLM、Ollama、自部署方案边界已经明确;
- 模型名、base_url、timeout、max_retries 通过配置管理;
- 已检查
deepseek-chat、deepseek-reasoner弃用计划,避免长期写死旧模型名; - 海外 GPU 不直接暴露给业务系统,前面有网关或队列;
- 大文件先清洗、摘要或对象存储化,避免跨境反复传输;
- 模型下载有缓存、校验和版本记录;
- API 错误、网络错误、推理错误、队列错误分开记录;
- 任务队列支持重试、取消、超时和失败回放;
- 监控覆盖网络链路、队列、GPU、模型服务和业务成功率;
- API Key、模型仓库 token、网络认证信息不进入代码仓库;
- 生产流量上线前完成小流量灰度和长时间稳定性测试;
- 回滚路径已经演练,不只停留在文档里。
十二、灰度发布与故障回滚
DeepSeek 本地部署进入生产前,不建议一次性把全部请求切到新模型或新 GPU 集群。更稳妥的方式是通过网关做灰度:
| 阶段 | 流量比例 | 观察指标 |
|---|---|---|
| 内部测试 | 0%外部流量 | 模型加载、基础问答、日志完整性 |
| 小流量灰度 | 1%-5% | 错误率、首 token 延迟、队列等待 |
| 扩大灰度 | 10%-30% | GPU显存、吞吐、网络超时 |
| 全量切换 | 100% | 成本、稳定性、回滚能力 |
回滚策略也要提前设计。模型版本、推理镜像、环境变量、网关路由和网络出口都要有可恢复版本。出现 5xx 激增、队列等待持续升高、跨境链路超时变多时,不要让业务代码临时判断,而应由网关或调度层切回上一组稳定节点。
总结
DeepSeek 本地部署和海外算力调度,不能只看模型能不能启动。真正影响生产效果的是模型版本、推理服务、任务队列、跨境链路、监控体系和回滚能力。
官方 API 适合快速接入,本地部署适合数据和服务可控,海外算力适合 GPU 资源弹性调度。团队需要根据业务时延、数据边界、成本和运维能力选择路径。架构上把业务、网关、队列、推理服务、模型缓存和网络链路分层,后续扩容、排障和模型升级才会更稳定。
参考资料
- DeepSeek API 官方文档:https://api-docs.deepseek.com/
- DeepSeek Hugging Face 主页:https://huggingface.co/deepseek-ai
- vLLM Quickstart:https://docs.vllm.ai/en/latest/getting_started/quickstart/
- vLLM OpenAI-Compatible Server:https://docs.vllm.ai/en/latest/serving/openai_compatible_server/
- Ollama 官方 API 文档:https://github.com/ollama/ollama/blob/main/docs/api.md

1323

被折叠的 条评论
为什么被折叠?



