Skip to content

本地模型部署

本地模型部署不是“把一个大模型下载到电脑里跑起来”这么简单。商用场景真正关心的是:

模型能不能稳定提供服务,数据能不能留在内网,响应速度和并发是否够用,成本是否可控,出问题能不能排查,后续能不能升级和回滚。

零基础先记住一句话:

本地部署解决的是“模型服务在哪里运行、由谁管理、数据是否离开内网、推理资源够不够”的问题,不等于模型能力一定更强,也不等于成本一定更低。

学习目标

学完本页,你应该能回答:

  1. 本地部署和云模型 API 的区别。
  2. 为什么本地部署要考虑模型文件、运行时、推理服务、业务后端和监控。
  3. CPU、内存、GPU、显存分别影响什么。
  4. 参数量、量化、上下文长度、并发和吞吐之间是什么关系。
  5. Ollama、llama.cpp、vLLM、TGI、Docker 部署分别适合什么。
  6. 一个本地模型服务如何接入业务后端。
  7. 为什么前端不能直接访问模型服务。
  8. 如何做健康检查、超时、重试、限流、降级和日志。
  9. 本地模型慢、启动失败、显存不足、中文效果差时怎么排查。
  10. 面试时如何讲本地模型部署的架构和取舍。

本地部署是什么

本地部署是把模型文件、推理运行时和推理服务部署在自己的机器、服务器或私有云里,由自己的后端系统调用。

mermaid
flowchart TD
    A["用户浏览器"] --> B["业务后端"]
    B --> C["AI 网关或模型适配层"]
    C --> D["本地推理服务"]
    D --> E["模型文件和运行时"]
    C --> F["日志、限流、监控"]
    C --> G["RAG 检索和工具服务"]

各层职责:

层级职责
用户浏览器发起聊天、问答、摘要等请求
业务后端鉴权、限流、参数校验、业务编排
AI 网关/适配层屏蔽 Ollama、vLLM、云 API 等差异
本地推理服务接收 Prompt,加载模型,生成 Token
模型文件和运行时保存权重,负责推理计算
监控日志记录耗时、错误、token、资源使用

不要让前端直接调用本地模型服务。前端没有可靠权限边界,也不适合暴露内部地址、模型接口、系统提示词和安全策略。

为什么需要本地部署

本地部署通常是为了以下目标:

目标说明
数据隐私敏感文档、日志、客户资料、医疗数据不离开内网
离线可用外部网络不可用时仍能使用
可控性模型版本、服务参数、日志策略自己控制
成本可预测高频固定场景可能比长期 API 调用更可控
私有知识库与内网向量库、数据库、权限系统结合
实验验证低成本验证 RAG、Agent、工具调用流程

但本地部署也有代价:

代价说明
硬件成本GPU、显存、服务器、存储
运维成本部署、升级、监控、故障处理
能力边界本地中小模型能力可能弱于顶级云模型
并发压力多用户服务需要排队、批处理或扩容
模型管理模型文件大,版本多,升级要评估

所以本地部署不是“更高级”,而是安全、成本、性能、维护复杂度之间的取舍。

本地部署和云模型 API 对比

对比项本地部署云模型 API
数据位置数据留在本地或内网数据发送到云服务
上手难度需要安装运行时和模型申请 Key 后即可调用
模型能力取决于本地模型和硬件通常更强、更新更快
成本结构硬件和运维固定成本按 token 或请求付费
并发能力自己扩容和调度云服务托管
可控性高,可控模型和参数受供应商能力影响
适合场景内网、隐私、固定高频、实验通用生产、高质量推理、弹性并发

实际项目常用混合策略:

  1. 低风险、高质量要求:用云模型。
  2. 高隐私、内网资料:用本地模型。
  3. 简单分类、摘要:用本地小模型。
  4. 复杂推理、高价值问题:路由到强模型。

本地推理的核心组件

mermaid
flowchart TD
    A["模型文件"] --> B["推理运行时"]
    B --> C["推理服务 API"]
    C --> D["业务适配层"]
    D --> E["业务应用"]
    B --> F["CPU / GPU / 内存 / 显存"]

模型文件

模型文件保存了模型权重、Tokenizer、配置和可能的量化格式。

常见内容:

内容作用
权重文件模型参数,是模型能力的主体
Tokenizer把文本切成 token,并把 token 转回文本
config层数、隐藏维度、上下文长度等配置
量化文件降低显存和内存占用的模型格式

推理运行时

运行时负责加载模型、管理内存、执行矩阵计算、生成 token。

常见运行时:

工具特点适合
Ollama安装简单,模型管理方便,有 HTTP API个人学习、本地开发、轻量内网服务
llama.cpp轻量,CPU 和量化支持好低资源机器、嵌入式、离线实验
vLLM高吞吐,支持服务化和连续批处理GPU 服务器、多用户并发
TGIHugging Face 生态推理服务标准化模型服务、团队部署
Docker封装运行环境团队交付、测试环境、私有化部署

推理服务 API

推理服务把模型能力暴露成 HTTP 接口,例如:

  1. /chat:普通对话。
  2. /generate:文本生成。
  3. /embeddings:生成向量。
  4. /health:健康检查。

业务系统不应该到处直接调用某个具体接口,而应该通过统一适配层。

推理过程怎么工作

mermaid
flowchart TD
    A["输入文本"] --> B["Tokenizer 切成 token"]
    B --> C["模型读取上下文"]
    C --> D["预测下一个 token 概率"]
    D --> E["采样或选择 token"]
    E --> F["把新 token 加入上下文"]
    F --> G{"是否结束"}
    G -- "否" --> C
    G -- "是" --> H["Tokenizer 解码成文本"]

关键点:

  1. 大模型通常是逐 token 生成,不是一次性生成整段答案。
  2. 上下文越长,每一步需要处理的信息越多。
  3. 输出越长,循环次数越多。
  4. 模型越大,每一步计算量越大。
  5. 并发越高,显存、队列和调度压力越大。

这就是为什么 AI 接口通常比普通接口慢,也更需要流式输出、限流和超时。

参数量、量化和资源

参数量是什么

7B、14B、32B 里的 B 是 billion,表示十亿级参数量。参数量越大,通常模型能力越强,但资源要求也更高。

简单理解:

参数量特点
1B 到 3B资源要求低,适合简单分类、摘要、实验
7B 到 8B入门常用,能做基础问答和 RAG
14B能力更强,资源压力明显增加
32B 以上更强但部署门槛高,通常需要较好 GPU

量化是什么

量化是把模型权重用更低精度存储和计算,例如从 FP16 变成 INT8、INT4、Q4。

mermaid
flowchart TD
    A["原始模型:精度高、占用大"] --> B["量化"]
    B --> C["占用更小、速度可能更快"]
    C --> D["部分场景效果可能下降"]

量化的价值:

  1. 降低显存和内存占用。
  2. 让普通机器也能跑较大模型。
  3. 降低部署成本。

量化的代价:

  1. 可能损失推理质量。
  2. 数学、代码、复杂推理可能更明显退化。
  3. 不同量化格式速度和效果不同。

面试时不要说“量化一定变差”或“量化一定更快”。正确说法是:量化通过降低权重精度减少资源占用,但效果和速度要结合模型、硬件、运行时、任务评测验证。

资源估算

部署前要看四类资源:

资源影响
CPUCPU 推理速度、数据预处理、服务调度
内存模型加载、上下文、并发请求、向量库
GPU矩阵计算速度
显存模型权重、KV Cache、并发上下文

显存为什么重要

推理时显存主要被这些东西占用:

  1. 模型权重。
  2. KV Cache。
  3. 输入输出上下文。
  4. 批处理和并发请求。
  5. 运行时额外开销。

KV Cache 用来缓存历史 token 的 Key/Value,避免每生成一个 token 都完全重算历史上下文。它能提高速度,但会占用显存,且上下文越长、并发越高,占用越大。

mermaid
flowchart TD
    A["并发请求增加"] --> B["每个请求都有上下文"]
    B --> C["KV Cache 增加"]
    C --> D["显存占用上升"]
    D --> E{"显存是否足够"}
    E -- "足够" --> F["正常生成"]
    E -- "不足" --> G["OOM、排队、降速或失败"]

资源估算思路

不要只问“某模型要多少显存”。还要问:

  1. 模型参数量多大?
  2. 是否量化?
  3. 上下文长度设置多少?
  4. 同时支持多少用户?
  5. 是否流式输出?
  6. 目标 P95 延迟是多少?
  7. 是否还要同机跑向量库、Rerank、业务服务?

资源估算的正确方式是:先小规模跑通,再用真实 Prompt、真实上下文、真实并发压测。

部署架构选择

个人学习架构

mermaid
flowchart TD
    A["浏览器或命令行"] --> B["本机后端"]
    B --> C["Ollama"]
    C --> D["本机模型"]

适合:

  1. 学习 RAG、Prompt、工具调用。
  2. 不追求高并发。
  3. 单机可用。

企业内网架构

mermaid
flowchart TD
    A["用户"] --> B["业务系统"]
    B --> C["AI 网关"]
    C --> D["模型服务集群"]
    C --> E["向量检索服务"]
    C --> F["工具服务"]
    D --> G["GPU 节点"]
    C --> H["日志、监控、审计"]

适合:

  1. 多用户访问。
  2. 需要权限、审计、限流。
  3. 需要与内部知识库和业务系统集成。

混合模型架构

mermaid
flowchart TD
    A["AI 请求"] --> B{"任务类型和风险"}
    B -- "简单、低风险" --> C["本地小模型"]
    B -- "企业私有资料" --> D["本地模型 + RAG"]
    B -- "复杂推理" --> E["云端强模型"]
    B -- "高风险操作" --> F["人工审批或强校验"]

这种架构更接近商用现实:不是所有请求都走同一个模型。

模型制品从仓库到显存的完整过程

mermaid
flowchart TD
    A["批准的模型仓库或制品库"] --> B["下载到临时目录"]
    B --> C["校验清单、Hash、大小和签名"]
    C --> D["校验config、Tokenizer和权重分片"]
    D --> E["原子发布到本地模型缓存"]
    E --> F["运行时解析配置并保留地址空间"]
    F --> G["加载或映射权重"]
    G --> H["初始化GPU Kernel和通信组"]
    H --> I["分配KV与工作区"]
    I --> J["预热并执行已知请求"]
    J --> K["Readiness通过后接流量"]

为什么不能边下载边对外服务

大模型通常由多个权重分片、配置和Tokenizer共同组成。某个分片缺失、Hash错误或Tokenizer来自另一Revision,都可能导致启动失败或更隐蔽的质量错误。

安全发布顺序:

  1. 下载到带唯一构建号的临时目录。
  2. 校验文件允许列表、大小、Hash/签名和完整分片清单。
  3. 拒绝符号链接越界、未知可执行文件和未批准远程自定义代码。
  4. 加载最小元数据验证架构、dtype、Tokenizer和License。
  5. 在同一文件系统使用原子重命名发布完整目录。
  6. 生成不可变 modelRevision,服务只引用该Revision。
  7. 旧版本保留到新版本观察期结束。

如果直接覆盖 models/current 中的文件,多个Worker可能分别读到新旧分片,回滚也无法恢复一致状态。

权重怎样进入内存或显存

  • CPU运行时可使用内存映射,让操作系统按页加载权重;首次访问可能发生Page Fault,因此“进程启动”不代表已预热。
  • GPU运行时通常从磁盘读到主机内存,再复制到设备显存;部分框架支持分片加载、CPU Offload或直接存储优化。
  • 多GPU部署需要按Tensor/Pipeline/Expert策略把权重放到对应设备,并建立通信组。
  • 权重加载完成后还需分配KV Cache、Kernel工作区和运行时Buffer。

所以磁盘模型大小不能直接等于峰值显存。需要同时核算权重精度、KV、激活/工作区、CUDA Context、通信Buffer和碎片。

可运行Demo:模型Manifest完整性校验

下面使用标准库模拟“临时目录验收后才发布”。为避免教学代码修改真实目录,Demo只校验内存中的文件内容和Manifest。

python
import hashlib


def sha256(data: bytes) -> str:
    return hashlib.sha256(data).hexdigest()


files = {
    "config.json": b'{"model_type":"demo","layers":32}',
    "tokenizer.json": b'{"revision":"tokenizer-v3"}',
    "model-00001.safetensors": b"weight-shard-1",
    "model-00002.safetensors": b"weight-shard-2",
}

manifest = {
    path: {"size": len(content), "sha256": sha256(content)}
    for path, content in files.items()
}


def validate_artifact(actual_files: dict[str, bytes], expected: dict) -> list[str]:
    errors = []
    if set(actual_files) != set(expected):
        errors.append("文件集合与Manifest不一致")
    for path, rule in expected.items():
        content = actual_files.get(path)
        if content is None:
            continue
        if len(content) != rule["size"]:
            errors.append(f"{path}:size不一致")
        if sha256(content) != rule["sha256"]:
            errors.append(f"{path}:sha256不一致")
    return errors


print("complete artifact:", validate_artifact(files, manifest))
tampered = {**files, "model-00002.safetensors": b"changed-weight"}
print("tampered artifact:", validate_artifact(tampered, manifest))
incomplete = {key: value for key, value in files.items() if "00002" not in key}
print("incomplete artifact:", validate_artifact(incomplete, manifest))

真实系统还应验证签名、发布者身份、模型格式安全、配置兼容和制品来源。Hash能发现内容变化,但不能证明内容本身可信。

GPU软件栈为什么经常不兼容

text
宿主机GPU硬件
→ 宿主机驱动
→ 容器GPU Runtime
→ 容器中的CUDA用户态库
→ PyTorch/推理引擎
→ Kernel和模型dtype

各层职责:

作用常见故障
GPU Driver控制硬件并提供内核接口驱动过旧、设备不可见、Xid错误
Container Runtime把设备和驱动能力注入容器容器没有GPU、权限错误
CUDA Runtime/Library提供用户态计算库与框架构建版本不兼容
PyTorch/Engine图执行、Kernel、调度和服务缺少目标架构Kernel、符号错误
NCCL/通信层多GPU集合通信拓扑、网卡、超时和版本问题

容器包含CUDA用户态库,不代表可以忽略宿主机驱动。镜像在A机器可运行,也不证明在不同GPU代际、驱动和互联拓扑的B机器可运行。

上线前保存并核对:GPU型号、驱动、容器镜像digest、CUDA/框架/引擎Revision、通信库和模型Revision。不要只记录“用了某某GPU”。

生产进程拓扑

mermaid
flowchart TD
    A["业务后端"] --> B["AI网关/路由"]
    B --> C["模型API Server"]
    C --> D["Scheduler"]
    D --> E["GPU Worker 0"]
    D --> F["GPU Worker 1"]
    E --> G["模型分片、KV和Kernel"]
    F --> G
    C --> H["Metrics、Trace和Audit"]
  • API Server负责协议、认证后的内部调用、流式连接和取消。
  • Scheduler负责队列、Continuous Batching、Token预算和公平。
  • Worker拥有模型权重、KV Cache和设备上下文。
  • Gateway负责场景路由、租户配额、模型Revision和降级。

不要在每个Web Worker中各加载一份完整模型。多进程若没有明确共享或设备分配,会重复占满显存。进程数、GPU可见设备和并行拓扑必须显式配置。

启动、存活、就绪和预热不是一回事

mermaid
flowchart TD
    A["进程创建"] --> B["读取配置和Manifest"]
    B --> C["加载Tokenizer和权重"]
    C --> D["初始化GPU、通信组和KV池"]
    D --> E["执行预热请求"]
    E --> F["校验输出、显存和模型Revision"]
    F --> G["Readiness=true"]
    G --> H["接收生产流量"]

Startup Probe

模型首次加载可能需要数分钟。Startup Probe 用于告诉编排系统“仍在初始化”,避免Liveness过早重启形成永久启动循环。

Liveness Probe

回答“进程是否陷入不可恢复状态”。只检查端口能连接太弱:API线程活着但GPU Worker已崩也可能返回200。Liveness也不能执行昂贵生成,否则探针会加重拥塞并触发雪崩。

Readiness Probe

回答“此刻是否应该接新流量”,至少考虑:

  • 模型与Tokenizer Revision加载完成。
  • 所需Worker和通信组健康。
  • 预热/自检通过。
  • 未处于排空、过载保护或模型切换状态。
  • 控制面路由和安全策略可用。

进程可以 live=trueready=false:它仍活着,但正在加载、排空或过载,不应接新请求。

预热为什么必要

第一次请求可能触发:

  • 模型文件页面首次读入。
  • GPU Context和显存池初始化。
  • Kernel加载、JIT或图捕获。
  • 通信组建立。
  • Prefix Cache尚未建立。

若实例一启动就加入负载均衡,真实用户会承担冷启动,P99突然恶化。预热应覆盖目标模型、典型短/长Shape、流式路径和结构化输出,但不能用生产敏感Prompt。

预热成功不等于容量通过;它只证明基本执行链可用。

优雅终止和排空

mermaid
flowchart TD
    A["收到终止或准备升级"] --> B["Readiness=false停止新流量"]
    B --> C["Gateway停止向该实例路由"]
    C --> D["等待在途Prefill、Decode和SSE"]
    D --> E{"是否在终止宽限期内完成"}
    E -- "是" --> F["保存审计并释放KV与通信资源"]
    E -- "否" --> G["传播取消并标记中断"]
    G --> F
    F --> H["进程退出"]

仅捕获SIGTERM后立即退出会截断流式回答;只无限等待又会阻塞发布。需要:

  • 先停止准入。
  • 为在途请求设置排空Deadline。
  • 向上游Provider/Worker传播取消。
  • 标记部分响应不可作为完整成功样本。
  • 写Tool在终止时按幂等键确认结果,不能假设中断就是失败。

滚动升级为什么可能造成显存不足

普通Web服务滚动发布会先启动新Pod再停止旧Pod。GPU节点若没有足够冗余,旧模型占着显存时新模型无法加载,形成 maxSurge 启动失败。

可选策略:

策略优点风险与条件
Rolling自动逐步替换需要额外GPU/显存容量
Recreate不需要双份资源有停机窗口
Blue/Green GPU池快速切流和回滚成本高,需要完整备用池
Canary独立节点风险隔离、可比较样本和容量有限

生产AI通常将模型Revision和应用Revision绑定为不可变Bundle,在独立容量完成加载、预热、评测后再切路由。旧实例要等在途和观察期结束后释放,不能切流瞬间删除回滚目标。

多副本路由和会话

无状态单轮请求可分配到任意同Revision副本;多轮会话的历史若由后端集中保存,也可跨副本重建Prompt。依赖本机Prefix Cache或会话状态时,稳定路由能提高命中,但实例故障仍要能够从权威状态恢复。

路由至少考虑:

  • 模型和Tokenizer Revision。
  • 租户、数据级别和场景风险。
  • GPU可用KV Token预算,而不只是请求数。
  • 当前Queue、TTFT和Deadline。
  • 并行组整体健康,不能只看一个Worker。

模型API契约和流式取消

统一适配层不能假设所有本地运行时能力相同。契约应声明:

  • Chat、Completion、Embedding分别支持什么。
  • 最大输入/输出和总上下文。
  • Tool、JSON Schema、多模态和Logprobs能力。
  • Usage在流式中何时返回。
  • Finish Reason和错误分类。
  • 是否支持Seed、取消和幂等请求ID。

SSE链路:

text
浏览器断连
→ 业务后端检测取消
→ AI网关取消模型请求
→ Scheduler移除等待/执行请求
→ Worker释放KV页

如果取消只停在浏览器,模型仍会继续生成、占用GPU并计费。

Ollama 快速部署 Demo

适合个人学习和本地开发。

bash
# 查看是否安装成功
ollama --version

# 下载模型,模型名称按实际环境选择
ollama pull qwen2.5:7b

# 命令行运行
ollama run qwen2.5:7b

# 调用本地 HTTP 接口
curl http://127.0.0.1:11434/api/chat -d '{
  "model": "qwen2.5:7b",
  "messages": [
    {"role": "user", "content": "用一句话解释什么是 RAG"}
  ],
  "stream": false
}'

Python 调用:

python
import requests


def chat_with_ollama(message: str) -> str:
    response = requests.post(
        "http://127.0.0.1:11434/api/chat",
        json={
            "model": "qwen2.5:7b",
            "messages": [
                {"role": "system", "content": "你是一个简洁的技术助手。"},
                {"role": "user", "content": message},
            ],
            "stream": False,
        },
        timeout=60,
    )
    response.raise_for_status()
    return response.json()["message"]["content"]


print(chat_with_ollama("解释本地模型部署的优缺点"))

后端适配层 Demo

业务系统不要直接散落调用 Ollama。建议封装适配层,未来可以切换到 vLLM 或云模型。

python
from __future__ import annotations

from dataclasses import dataclass
import time
import requests


@dataclass
class ChatResult:
    answer: str
    model: str
    latency_ms: int


class LocalModelClient:
    def __init__(self, base_url: str, model: str) -> None:
        self.base_url = base_url.rstrip("/")
        self.model = model

    def health_check(self) -> bool:
        try:
            response = requests.get(f"{self.base_url}/api/tags", timeout=3)
            return response.status_code == 200
        except requests.RequestException:
            return False

    def chat(self, message: str, timeout: int = 60) -> ChatResult:
        if not message.strip():
            raise ValueError("message is empty")

        start = time.time()
        response = requests.post(
            f"{self.base_url}/api/chat",
            json={
                "model": self.model,
                "messages": [{"role": "user", "content": message}],
                "stream": False,
            },
            timeout=timeout,
        )
        response.raise_for_status()
        data = response.json()
        return ChatResult(
            answer=data["message"]["content"],
            model=self.model,
            latency_ms=int((time.time() - start) * 1000),
        )


client = LocalModelClient("http://127.0.0.1:11434", "qwen2.5:7b")
if client.health_check():
    print(client.chat("什么是本地模型部署?"))
else:
    print("local model service is not healthy")

这个 Demo 体现了几件生产意识:

  1. 统一封装模型客户端。
  2. 有健康检查。
  3. 有超时。
  4. 返回模型名和耗时。
  5. 输入为空时提前校验。

真实项目还要补:鉴权、限流、重试、日志、traceId、token 统计、fallback。

Docker 部署思路

团队协作时,Docker 的价值是环境可复现。

mermaid
flowchart TD
    A["Docker 镜像"] --> B["固定运行时和依赖"]
    B --> C["挂载模型目录"]
    C --> D["暴露模型服务端口"]
    D --> E["业务后端通过内网调用"]

注意点:

说明
模型文件通常挂载到容器,不建议打进镜像
GPU需要宿主机驱动和容器运行时支持
端口只暴露给内网或业务后端
日志输出到标准输出或采集系统
健康检查容器编排依赖健康状态
资源限制限制 CPU、内存,避免拖垮宿主机

本地模型服务不要裸露到公网。即使没有 API Key,开放模型接口也可能被滥用导致资源耗尽和数据泄露。

商业场景:医疗数据资产平台

本地模型适合在医疗数据资产平台里做这些能力:

场景为什么适合本地
数据标准问答制度和字段口径可能属于内部资料
资产摘要数据资产名称、字段、敏感级别可在内网处理
采集异常解释日志和错误信息不方便发到外部
权限内知识库问答结合租户、部门、角色过滤 RAG
离线报告初稿对实时性要求低,更看重隐私

不建议直接本地模型处理的情况:

  1. 需要非常强推理能力的复杂分析。
  2. 高风险医疗诊断结论。
  3. 高并发实时在线客服,且本地资源不足。
  4. 没有评估集证明本地模型质量足够。

生产监控指标

本地部署至少要监控两类指标:系统资源和模型服务。

类型指标说明
系统CPU、内存、磁盘、网络判断机器基础状态
GPU显存占用、GPU 利用率、温度判断推理资源瓶颈
服务QPS、并发数、排队长度判断请求压力
延迟首 token、总耗时、P95/P99判断用户体验
质量拒答率、反馈、RAG 引用命中判断回答是否可用
成本机器成本、能耗、维护成本判断是否比云模型合算
错误超时、OOM、连接失败判断稳定性

日志至少记录:

text
requestId、userId、model、promptVersion、inputTokens、outputTokens、
latencyMs、status、errorCode、host、gpuId

生产排查流程

mermaid
flowchart TD
    A["本地模型服务异常"] --> B{"是否能访问服务"}
    B -- "不能" --> C["检查进程、端口、容器、日志"]
    B -- "能" --> D{"是否启动模型失败"}
    D -- "是" --> E["检查模型文件、磁盘、内存、显存"]
    D -- "否" --> F{"是否响应慢"}
    F -- "是" --> G["检查上下文长度、并发、GPU、KV Cache"]
    F -- "否" --> H{"是否回答质量差"}
    H -- "是" --> I["检查模型能力、Prompt、RAG、评估集"]
    H -- "否" --> J["检查业务后端、网络、超时和限流"]

模型启动失败

排查:

  1. 模型名称是否正确。
  2. 模型文件是否下载完整。
  3. 磁盘空间是否足够。
  4. 内存或显存是否不足。
  5. 端口是否被占用。
  6. 运行时版本是否兼容。

显存不足或 OOM

解决方向:

  1. 换更小模型。
  2. 使用量化模型。
  3. 降低上下文长度。
  4. 降低并发数。
  5. 单独部署模型服务,不和向量库抢资源。
  6. 使用更高显存 GPU 或多机部署。

回答很慢

排查:

  1. 是首 token 慢,还是总生成慢。
  2. Prompt 是否太长。
  3. RAG TopK 是否太大。
  4. 输出是否太长。
  5. 是否 CPU 推理。
  6. 并发是否导致排队。
  7. 是否存在网络或后端超时。

中文效果差或答非所问

排查:

  1. 模型中文能力是否足够。
  2. Prompt 是否清楚。
  3. RAG 召回资料是否正确。
  4. 量化是否导致质量下降。
  5. 是否需要换模型、加 Rerank、改切分或补评估集。

常见坑

后果正确做法
直接让前端调模型服务暴露内部接口,绕过权限前端只调业务后端
只看模型能否启动上线后并发和延迟不可控用真实 Prompt 压测
盲目追求大模型资源不够,体验很差按场景选择模型和量化
不做适配层切模型要改大量业务代码封装统一 Chat/Embedding 接口
不记录版本质量下降无法定位记录模型、Prompt、知识库版本
不限制调用模型服务被刷爆加鉴权、限流、配额
不做降级模型失败导致业务不可用超时、重试、fallback、友好提示
把敏感日志发给模型数据泄露风险脱敏、最小化、权限审计

面试标准回答

本地模型部署是什么?

可以这样答:

text
本地模型部署是把模型文件、推理运行时和模型服务部署在自己的服务器、内网或私有云里,由业务后端通过统一适配层调用。它常用于数据隐私、离线可用、企业知识库和固定高频场景。生产上不能只看模型能不能跑,还要关注硬件资源、量化、上下文长度、并发、流式输出、健康检查、日志监控、限流降级和版本回滚。

本地部署和云模型 API 怎么选?

云模型 API 上手快、能力强、弹性好,但数据会出内网且按 token 计费。本地部署数据可控、适合隐私和内网场景,但要自己承担硬件、运维、并发、监控和升级。实际项目常用混合架构:简单低风险走本地模型,复杂推理或高质量要求走云模型,敏感资料结合本地 RAG。

为什么本地模型也要经过业务后端?

因为业务后端负责鉴权、限流、参数校验、Prompt 编排、RAG 权限过滤、日志审计和安全控制。如果前端直接调用模型服务,就绕过了权限和审计,也容易暴露内部地址和系统提示词。

显存不足怎么处理?

可以换更小模型、使用量化模型、降低上下文长度、减少并发、减少 RAG 片段、关闭不必要服务,或者升级 GPU 和拆分部署。排查时要区分模型权重占用、KV Cache、并发请求和运行时开销。

本地模型回答慢怎么排查?

先看是首 token 慢还是总耗时慢,再检查 Prompt 长度、RAG TopK、输出长度、并发排队、CPU/GPU 使用、KV Cache、网络和后端超时。不要一上来就换模型,先用日志和监控定位瓶颈。

关联知识点

知识点作用
大模型基础理解 token、上下文、采样和幻觉
Transformer原理理解为什么模型逐 token 生成
推理优化学习流式输出、缓存、模型路由、限流
RAG知识库理解本地模型如何结合企业知识库
RAG数据治理理解本地知识库的版本、权限、发布和回滚
AI应用架构学习 AI 网关、适配层和业务集成
LLMOps学习模型、Prompt、知识库的治理体系
AI安全理解本地部署中的权限、脱敏和审计
AI面试题查看本地部署相关面试回答

本章小结

本地模型部署的关键不是“能不能跑起来”,而是“能不能稳定、安全、可排查地成为业务能力”。零基础学习时先理解五件事:模型文件是什么,运行时怎么生成 token,硬件资源为什么影响速度和并发,业务后端为什么要做适配和安全控制,线上问题如何通过日志和监控排查。