本地部署 Langchain-Chatchat:从零构建离线知识库问答系统

在企业级 AI 应用中,如何安全地利用大模型处理私有文档,始终是一个关键挑战。将敏感数据上传到云端显然不可接受,而依赖外部 API 又存在泄露风险。于是,“本地化部署”成了高安全场景下的唯一选择。

最近我在为某金融客户搭建内部知识助手时,再次验证了 Langchain-Chatchat 的成熟度与实用性。它不仅支持多种格式的文档解析(PDF、Word、Excel 等),还能通过向量数据库实现精准检索,并结合本地运行的大语言模型生成自然回答——整个流程完全离线,真正做到“数据不出内网”。

本文记录的是基于最新版本 langchain-chatchat 的全流程实操经验,环境为 CentOS 7 + CUDA 12.2 + Python 3.10,所有步骤均已亲测可复现。不同于网上碎片化的教程,我将带你完整走完从环境隔离、模型服务配置到知识库初始化的每一步,尤其重点解决新手常遇到的模型加载失败、依赖冲突和连接异常等问题。


系统准备与组件选型

要跑通这套系统,硬件和软件基础必须到位。如果你只是想调试功能,CPU 模式勉强可用,但体验会非常卡顿;真正有意义的应用,建议至少配备一块显存 ≥16GB 的 NVIDIA 显卡(如 A100、RTX 3090/4090)。

以下是推荐配置:

项目 要求
操作系统 Linux(CentOS 7 / Ubuntu 20.04+)或 Windows WSL2
GPU NVIDIA 显卡,显存 ≥16GB
CUDA 版本 11.8 或 12.x(实测 12.2 表现稳定)
CPU 多核处理器(≥8 核)
内存 ≥32GB
存储空间 ≥100GB(用于存放模型文件及向量库)

为什么选这个组合?因为现代 LLM 推理对显存极其敏感。以 Qwen2-7B-Instruct 为例,FP16 加载需要约 14GB 显存,一旦超限就会 OOM 报错。量化虽能降低占用,但也会影响推理质量。因此,在资源允许的情况下,优先保障显存充足。

至于技术栈的选择,我采用了 Xinference 作为模型服务框架。相比直接调用 HuggingFace Transformers,它的优势非常明显:

  • 提供统一 REST API 接口,便于集成;
  • 支持主流国产模型(通义千问、百川、BGE 等)一键部署;
  • 自带 Web 控制台,可视化管理模型实例;
  • 可跨节点扩展,适合未来横向扩容。

整个系统的架构逻辑也很清晰:

graph TD
    A[用户提问] --> B(Web UI)
    B --> C{Chatchat 主程序}
    C --> D[调用 Xinference 的 LLM]
    C --> E[调用 Xinference 的 Embedding 模型]
    D --> F[生成答案]
    E --> G[向量数据库检索]
    G --> H[Chroma]
    F & H --> I[返回最终响应]

可以看到,核心计算模块是解耦的。Chatchat 负责业务流程编排,而具体模型推理交由 Xinference 托管,这种设计极大提升了系统的灵活性和可维护性。


环境隔离:创建独立 Conda 环境

Python 项目的最大痛点之一就是依赖冲突。Langchain-Chatchat 和 Xinference 对某些包的版本要求不同,若混在一起安装极易出错。所以第一步,必须做环境隔离。

我习惯使用 Miniconda 来管理虚拟环境。如果尚未安装,可以通过以下命令快速获取(以 Linux 为例):

wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh

安装过程中提示是否初始化 conda 时,输入 yes 即可。

接下来创建两个专用环境:

# 用于运行 chatchat 主程序
conda create -n chatchat python=3.10

# 用于运行 xinference 模型服务
conda create -n xinference python=3.10

这里统一使用 Python 3.10,是因为目前大多数 AI 框架对其兼容性最好,尤其是涉及 CUDA 加速的部分。版本过高或过低都可能引发难以排查的问题。

小贴士:国内用户建议配置清华源加速下载:

```yaml

~/.condarc

channels:
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free
- defaults
show_channel_urls: true
```


安装主程序:Langchain-Chatchat

激活 chatchat 环境后,执行安装命令:

conda activate chatchat
pip install -U "langchain-chatchat[xinference]"

注意这里的 [xinference] 是 extras_require 字段,表示额外安装与 Xinference 集成所需的依赖项,比如 xinference-clientrequests 等。如果不加这个标记,后续无法通过 API 调用远程模型服务。

安装过程可能会花费几分钟,期间 pip 会自动解决依赖树。如果出现网络超时,可以尝试更换 PyPI 源:

pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

启动模型服务:Xinference

现在切换到另一个战场——模型推理层。

先激活 xinference 环境:

conda activate xinference

然后启动服务端:

XINFERENCE_MODEL_SRC=modelscope xinference-local --host 0.0.0.0 --port 9997

解释几个关键参数:

  • XINFERENCE_MODEL_SRC=modelscope:告诉 Xinference 从魔搭社区自动拉取模型,无需手动下载;
  • --host 0.0.0.0:允许外部设备访问(比如你在本地浏览器查看服务器界面);
  • --port 9997:自定义端口,避免与其他服务冲突。

启动成功后,你会看到类似如下输出:

 ➜  Xinference is running at http://0.0.0.0:9997
    You can access the web UI in your browser.

打开浏览器访问 http://<your-server-ip>:9997,就能看到简洁直观的控制台界面。


部署语言模型:Qwen2-7B-Instruct

进入 Xinference Web 页面后,点击左侧 “Launch Model” → “LLM”,在搜索框输入 qwen,找到 qwen2-instruct 模型。

填写以下配置:

  • Model UID: qwen2-7b(自定义名称,后续需与此一致)
  • Model Size (in B): 7
  • Quantization: 推荐首次使用 none(非量化),确保最佳性能;若显存紧张可选 q4_K_M
  • GPU idx: 使用哪块 GPU,单卡填 0
  • Replica: 实例数量,默认 1

点击 “Launch” 后,Xinference 会自动从 ModelScope 下载模型权重。首次下载耗时较长(10–30 分钟,取决于网络速度),之后即可本地加载。

⚠️ 若提示“找不到模型”,请确认启动命令前已设置 XINFERENCE_MODEL_SRC=modelscope。否则 Xinference 默认不会启用 modelscope 源。


部署嵌入模型:bge-large-zh-v1.5

回到首页,点击 “EMBEDDING MODELS”,搜索 bge-large-zh,选择 bge-large-zh-v1.5

这是目前中文 RAG 场景下表现最出色的 Embedding 模型之一,尤其在语义匹配准确率上优于多数竞品。

配置选项如下:

  • Model UID: embedding-bge
  • Max sequence length: 512(默认即可)

点击 “Launch” 完成部署。该模型将在文档分块后进行向量化编码,直接影响检索精度。


初始化 Chatchat 配置

退出 Xinference 环境,回到 chatchat 环境:

conda deactivate
conda activate chatchat

设置项目根目录(按实际路径修改):

export CHATCHAT_ROOT=/home/LLM/langchain-chatchat
chatchat init

第一次运行时会出现黄色 WARNING:“未找到配置文件”。别担心,这说明初始化正在生成目录结构:

$CHATCHAT_ROOT/
├── configs/
├── data/
│   └── nltk_data/
├── knowledge_base/
│   └── samples/
├── models/
└── web_ui/

这些目录各有用途:
- configs/:存放 YAML 配置文件;
- knowledge_base/:你的私有文档放在这里;
- data/nltk_data/:NLTK 分词器依赖;
- web_ui/:前端页面资源。


配置模型地址:model_settings.yaml

最关键的一步来了——让 Chatchat 正确连接到 Xinference 中部署的模型。

编辑 $CHATCHAT_ROOT/configs/model_settings.yaml 文件,关键字段如下:

DEFAULT_LLM_MODEL: qwen2-instruct
DEFAULT_EMBEDDING_MODEL: bge-large-zh-v1.5

llm_models:
  - model_name: qwen2-instruct
    model_type: qwen
    server_address: http://localhost:9997
    local_model_path: ~
    prompt_name: default

embeddings:
  - model_name: bge-large-zh-v1.5
    model_path: ~
    server_address: http://localhost:9997

📌 注意事项:
- server_address 必须指向 Xinference 的实际 IP 和端口;
- model_name 不一定等于 Model UID,但建议保持一致以免混淆;
- 如果 Xinference 运行在远程服务器上,localhost 要换成真实 IP;
- 修改后务必保存,否则配置不生效。


补全 NLTK 依赖:punkt 与 tagger

很多人忽略了一个细节:Chatchat 在文本分块时依赖 NLTK 的分句工具,而这两个组件不会自动下载。

你需要手动获取:

  1. punkt 分词器
    - 下载地址:https://raw.githubusercontent.com/nltk/nltk_data/gh-pages/packages/tokenizers/punkt.zip
    - 解压后放入:$CHATCHAT_ROOT/data/nltk_data/tokenizers/punkt/

  2. averaged_perceptron_tagger 词性标注器
    - 下载地址:https://raw.githubusercontent.com/nltk/nltk_data/gh-pages/packages/taggers/averaged_perceptron_tagger.zip
    - 解压后放入:$CHATCHAT_ROOT/data/nltk_data/taggers/averaged_perceptron_tagger/

如果对应目录不存在,请提前创建:

mkdir -p $CHATCHAT_ROOT/data/nltk_data/{tokenizers,taggers}

否则运行时会抛出 LookupError: Resource [name] not found 错误。


构建知识库:向量化索引重建

一切就绪后,开始构建真正的“知识大脑”。

执行命令:

chatchat kb -r

这个 -r 参数表示 rebuild,即清空旧向量库并重新索引 knowledge_base/samples/ 目录下的所有文档。

整个过程包括:
1. 文档加载(支持 TXT、PDF、DOCX、XLSX 等);
2. 文本清洗与分块;
3. 调用 Xinference 的 embedding-bge 模型生成向量;
4. 存入本地 Chroma 数据库。

首次运行较慢,尤其是文档较多时,请耐心等待。完成后你会看到类似提示:

Successfully created vector store for knowledge base 'samples'

启动服务:Web 可视化界面

最后一步,启动前端服务:

chatchat start -a

-a 参数表示同时启动 API 和 Web UI 服务。

启动成功后,终端会显示:

INFO:     Uvicorn running on http://0.0.0.0:8501 (Press CTRL+C to quit)

此时打开浏览器访问:http://<your-server-ip>:8501

你将看到一个简洁的图形化界面,支持:
- 上传新文档;
- 选择知识库;
- 输入问题并获取回答;
- 查看检索到的相关片段。

试着问一句:“Langchain-Chatchat 支持哪些文档格式?”

系统会从样本库中检索相关信息,并由 Qwen2 生成自然语言回答:

“支持 TXT、PDF、Word(.docx)、Excel(.xlsx)、PPT、Markdown 等多种格式……”

全过程无需联网,全部在本地完成,真正实现了数据闭环。


常见问题避坑指南

即便严格按照流程操作,仍可能遇到一些“意料之外”的错误。以下是我在部署过程中总结的高频问题清单:

问题 原因 解决方案
Xinference 找不到模型 未设置 XINFERENCE_MODEL_SRC=modelscope 启动命令前加上该环境变量
CUDA out of memory 显存不足 改用量化模型(如 q4)或减少 batch size
Connection refused Xinference 未启动或地址错误 检查 model_settings.yamlserver_address
NLTK 报错“No such file” punkt 或 tagger 未下载 手动下载并放置到指定路径
知识库无法更新 未执行 kb -r 新增文档后必须重新运行重建命令
页面打不开(8501端口) 防火墙限制 开放端口或使用 SSH 端口转发

特别提醒:每次更换模型或修改配置后,记得重新执行 kb -r,否则旧的向量缓存可能导致结果偏差。


这种高度集成又灵活解耦的设计思路,正引领着智能知识系统向更可靠、更高效的方向演进。你可以在此基础上进一步拓展:

  • 添加自己的业务文档(产品手册、制度文件)到 knowledge_base
  • 替换其他 LLM(如 Baichuan、InternLM)进行效果对比;
  • 将系统接入企业微信、钉钉等 IM 工具,打造自动化客服机器人;
  • 结合 LangGraph 构建复杂 Agent 流程,实现多跳推理。

未来我也会陆续推出 Ollama 部署版、GPU 多卡并行优化、RAG 性能调优等系列文章。如果你正在探索本地大模型落地,欢迎持续关注。

有任何部署问题,也欢迎留言交流,我会第一时间回复。希望这篇实战笔记,能帮你少踩几个坑,早日跑通属于你自己的智能知识库。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐