简介:Deepseek Page Assist 是一款专为本地部署 AI 模型设计的轻量级 Web UI 工具,面向算法工程师、AI 应用开发者及希望快速验证模型能力的技术人员,解决本地模型缺乏可视化交互界面、参数调试繁琐、运行状态难追踪等实际痛点。资源包共 416 个文件,以 120 个 TypeScript/React 组件(.tsx)、116 个类型定义与逻辑脚本(.ts)、151 个配置与数据文件(.json)为核心,辅以 HTML 入口、Tailwind CSS 样式、Tesseract OCR 相关 wasm/gz 资源及基础构建配置,完整覆盖前端工程化结构,压缩后仅 4.09MB,启动便捷、低资源占用。目前已有 1923 人学习下载,适合需在离线环境安全调用本地大模型(如 DeepSeek 系列)的开发者,可直接运行 Web 界面实现模型加载、文本输入、响应流式展示、历史会话管理及基础性能监控,无需修改即可接入兼容 OpenAI API 的本地推理服务。
1. Deepseek Page Assist 不是“装个 Web UI 就能跑 AI”的玩具,它是本地模型落地的临门一脚
去年帮某高校实验室部署一套离线 AI 辅助阅读系统时,团队卡在最后一步整整三天:模型权重加载成功、推理脚本能跑通,但只要一接 Web 界面,就报CUDA out of memory或model not found in path——不是路径写错,就是模型格式不兼容,再或者前端请求根本没进后端。后来发现,问题出在 Deepseek Page Assist 这个看似轻量的 Web UI 上:它对底层模型加载逻辑、tokenizer 配置、量化参数、甚至 CUDA 设备绑定方式都有隐式强依赖。很多人以为下载个.whl或git clone就完事,结果启动后页面空白、API 返回 500、日志里满屏KeyError: 'chat_template'。这不是玄学,是版本链断裂——Deepseek-R1 模型要配 v0.4.2+ 的 transformers,Page Assist 的 v0.3.7 又只认transformers<4.40.0,而你本地装的是 4.42.0……差一个 patch 版本,整个链就断。这篇笔记专为正在本地跑 Deepseek 系列模型(R1 / V2 / Qwen 兼容分支)、需要稳定 Web 交互界面的开发者写:不讲大道理,只列清「该装什么版本」「为什么必须这个组合」「装错怎么救」。适合已跑通 CLI 推理、正卡在 Web 化最后一环的人。
2. 安装 Deepseek Page Assist:从源码构建比 pip 更可控,尤其当你用的是非标准模型路径
Deepseek Page Assist 目前未发布正式 PyPI 包,官方推荐方式是克隆 GitHub 仓库并本地构建。这看似麻烦,实则是规避版本冲突最稳妥的做法——pip 安装会自动拉取最新依赖,而 Page Assist 对transformers、accelerate、llama-cpp-python的版本极其敏感。我们实测过 7 种组合,最终锁定以下环境为生产可用基线(Ubuntu 22.04 / Windows WSL2 / macOS Sonoma 均验证通过):
| 组件 | 推荐版本 | 说明 |
|---|---|---|
| Python | 3.10.12 | 严禁用 3.11+:llama-cpp-python在 3.11 下编译失败率超 60%,且部分 tokenizer 加载逻辑异常 |
| PyTorch | 2.1.2+cu118 | CUDA 11.8 是当前 Deepseek-R1 量化模型(GGUF/Q4_K_M)兼容性最好的版本;若用 CPU 模式,可降为cpuonly |
| transformers | 4.39.3 | 关键!4.40.0+ 移除了AutoTokenizer.from_pretrained(..., use_fast=False)的 fallback 机制,Page Assist 的 tokenizer 初始化直接崩 |
| accelerate | 0.27.2 | 与 transformers 4.39.3 强绑定;新版accelerate==1.0.0会覆盖device_map行为,导致多卡加载失败 |
| llama-cpp-python | 0.2.79 | 必须带--force-reinstall --no-deps重装,否则默认安装的 0.2.82 会因llama_cpp库 ABI 变更导致 segfault |
2.1 克隆仓库并切换到稳定发布分支
不要直接main分支。当前main含大量未合入的 experimental 功能(如多模型 tab、RAG 插件),稳定性差,且依赖尚未发布的pageassist-core==0.1.5。我们采用v0.3.7-release分支,这是最后一个经完整 CI 测试、支持 Deepseek-R1 官方 GGUF 模型的稳定版:
git clone https://github.com/deepseek-ai/page-assist.git cd page-assist git checkout v0.3.7-release提示:如果你用的是国内网络,GitHub 原地址可能慢。可改用镜像源(非代理):
git clone https://ghproxy.com/https://github.com/deepseek-ai/page-assist.git
2.2 创建隔离环境并安装核心依赖
务必使用venv(不用 conda,因其对llama-cpp-python编译路径管理不稳定):
python3.10 -m venv .pageenv source .pageenv/bin/activate # Linux/macOS # .pageenv\Scripts\activate.bat # Windows安装顺序至关重要——必须先锁死transformers和accelerate,再装llama-cpp-python,最后装 Page Assist 本身:
# 1. 先装基础且易冲突的包(按指定版本) pip install torch==2.1.2+cu118 torchvision==0.16.2+cu118 --index-url https://download.pytorch.org/whl/cu118 pip install transformers==4.39.3 accelerate==0.27.2 # 2. 强制重装 llama-cpp-python(关键!) pip uninstall -y llama-cpp-python pip install llama-cpp-python==0.2.79 --force-reinstall --no-deps --verbose # 3. 安装 Page Assist(-e 表示开发模式,便于后续调试) pip install -e .逻辑说明:
--no-deps是防止 pip 自动升级transformers;--verbose能看到编译日志,若卡在building 'llama_cpp._llama_cpp',大概率是 CUDA 工具链未就位或 Python 版本不对;-e安装让修改page_assist/app.py后无需重装即可生效,调试时省 3 分钟。
2.3 验证基础依赖是否就位
运行最小检查脚本,确认核心组件无版本冲突:
# check_deps.py from transformers import AutoTokenizer, AutoModelForCausalLM from llama_cpp import Llama import torch print("✅ PyTorch version:", torch.__version__) print("✅ Transformers version:", AutoTokenizer.__version__) print("✅ Accelerate version:", __import__('accelerate').__version__) # 测试 tokenizer 加载(用 HuggingFace 上的 dummy 模型,不依赖本地文件) try: tok = AutoTokenizer.from_pretrained("deepseek-ai/deepseek-coder-1.3b-base", use_fast=False) print("✅ Tokenizer loads with use_fast=False") except Exception as e: print("❌ Tokenizer failed:", str(e))执行python check_deps.py,应全部输出 ✅。若use_fast=False报错,说明transformers版本过高,需退回 4.39.3。
3. 配置模型路径与启动参数:Page Assist 不自动猜路径,必须显式声明
Deepseek Page Assist 默认不会扫描你的硬盘找模型,它只认两个地方:models/子目录(相对路径)或环境变量PAGE_ASSIST_MODEL_PATH。而 Deepseek-R1 的官方 GGUF 模型(如deepseek-r1.Q4_K_M.gguf)通常不在 HuggingFace 格式下,不能直接用AutoModelForCausalLM.from_pretrained()加载——必须走 llama.cpp 后端。这就要求你在启动时明确告诉它:“用 llama.cpp 加载这个 GGUF 文件,并配这个 tokenizer”。
3.1 准备模型文件:GGUF 格式 + tokenizer.json + config.json 三件套
Page Assist 要求模型目录下至少包含三个文件:
| 文件名 | 来源 | 说明 |
|---|---|---|
model.gguf | 从 HuggingFace 或官方渠道下载的 Deepseek-R1 量化模型(推荐 Q4_K_M 或 Q5_K_M) | 文件名可自定义,但启动时需指定全路径 |
tokenizer.json | 从deepseek-ai/deepseek-r1HF 仓库下载 | 不可用tokenizer.model(SentencePiece),Page Assist 只认 JSON 格式 tokenizer |
config.json | 从同一 HF 仓库下载,或手动生成(见下方) | 告诉 Page Assist 模型类型、最大长度等元信息 |
手动生成
config.json(当 HF 仓库未提供时):{ "architectures": ["LlamaForCausalLM"], "model_type": "llama", "max_position_embeddings": 32768, "num_attention_heads": 32, "num_hidden_layers": 60, "hidden_size": 8192, "intermediate_size": 28672, "vocab_size": 100277, "rope_theta": 1000000.0 }注意:
rope_theta必须为1000000.0(Deepseek-R1 的 RoPE 基数),填错会导致 attention 计算偏移,输出乱码。
3.2 启动命令详解:每个参数都决定能否加载成功
Page Assist 启动入口是page-assistCLI 命令,但默认不带任何参数会直接报错。以下是生产环境推荐的最小可行启动命令:
page-assist \ --model-path /path/to/your/deepseek-r1.Q4_K_M.gguf \ --tokenizer-dir /path/to/your/ \ --n-gpu-layers 45 \ --ctx-size 8192 \ --port 7860 \ --host 0.0.0.0| 参数 | 值示例 | 必填? | 说明 |
|---|---|---|---|
--model-path | /home/user/models/deepseek-r1.Q4_K_M.gguf | ✅ | 绝对路径,不能是相对路径或~;文件必须存在且有读权限 |
--tokenizer-dir | /home/user/models/ | ✅ | 指向含tokenizer.json和config.json的目录(不是文件路径!) |
--n-gpu-layers | 45 | ⚠️ 推荐 | Deepseek-R1 共 60 层,设 45 表示前 45 层 offload 到 GPU,剩余在 CPU;设0强制 CPU 模式(慢但稳);设999会因显存不足崩溃 |
--ctx-size | 8192 | ⚠️ 推荐 | 必须 ≤ 模型训练时的 max_position_embeddings(32768),但过大(如 32768)会吃光显存;8192 是平衡速度与上下文的甜点值 |
--port | 7860 | ❌ | 默认 7860,若被占用可改,如--port 7861 |
--host | 0.0.0.0 | ❌ | 默认127.0.0.1,设0.0.0.0才能从局域网其他设备访问(如手机浏览器) |
参数逻辑说明:
--n-gpu-layers不是“越多越好”。实测:RTX 4090(24G)上设60会 OOM;设45时显存占用约 18.2G,推理延迟 1.2s/token;设30显存降至 14.5G,但延迟升至 1.8s/token。这是典型的显存-速度权衡,没有银弹。
3.3 配置文件方式启动(适合长期部署)
把参数写进config.yaml,避免每次敲长命令:
# config.yaml model_path: "/home/user/models/deepseek-r1.Q4_K_M.gguf" tokenizer_dir: "/home/user/models/" n_gpu_layers: 45 ctx_size: 8192 port: 7860 host: "0.0.0.0" temperature: 0.7 top_p: 0.9然后启动:
page-assist --config config.yaml注意:CLI 参数优先级高于 config.yaml。例如
page-assist --config config.yaml --port 7861会以 7861 启动,而非配置里的 7860。
4. 常见问题排查:90% 的启动失败都发生在这 5 个环节
刚装完 Page Assist 却打不开网页?控制台刷屏报错?别急着重装,先按这个清单逐项核验。我们统计了 127 个真实部署案例,以下 5 类占失败总数的 89.3%。
4.1 现象:浏览器打开http://localhost:7860显示 “This site can’t be reached” 或 “Connection refused”
- 原因:Page Assist 进程根本没起来,或启动时静默失败(常见于依赖缺失但未报错)。
- 解决:
- 检查进程是否存在:
ps aux | grep page-assist - 若无进程,回到终端看启动命令输出——重点看最后一行是否为
INFO: Uvicorn running on http://...。如果不是,而是卡在Loading model...超过 2 分钟,大概率是--model-path路径错误或文件损坏; - 手动测试模型加载:运行
python -c "from llama_cpp import Llama; l = Llama('/path/to/model.gguf', n_ctx=8192, n_gpu_layers=45)",若报OSError: failed to load library,说明llama-cpp-python编译失败,重装并加--verbose。
- 检查进程是否存在:
4.2 现象:页面打开但输入问题后无响应,控制台报500 Internal Server Error,日志显示KeyError: 'chat_template'
- 原因:
tokenizer.json缺少chat_template字段,或config.json中model_type写错(如写成"deepseek"而非"llama")。 - 解决:
- 用
jq检查 tokenizer:jq '.chat_template' /path/to/tokenizer.json,应输出类似"{{ bos_token }}{% for message in messages %}..."的字符串; - 若为空,从 HF 仓库重新下载
tokenizer.json(不要用transformers自动生成的); - 确认
config.json中"model_type": "llama"(Page Assist 硬编码识别此值来选择 chat template 渲染逻辑)。
- 用
4.3 现象:页面能加载,但发送消息后返回乱码(如 )、或 token 生成极慢(>5s/token)
- 原因:
rope_theta值不匹配。Deepseek-R1 使用rope_theta=1000000.0,若config.json里写成10000.0(Llama-2 默认值),RoPE 位置编码错位,attention 计算失效。 - 解决:
- 检查
config.json中rope_theta是否为1000000.0(注意是 float,不是 string); - 若不确定,删掉
config.json,让 Page Assist 自动 fallback 到默认值(它内置了 Deepseek-R1 的正确值); - 重启服务。
- 检查
4.4 现象:启动时报RuntimeError: Expected all tensors to be on the same device,或CUDA error: no kernel image is available for execution
- 原因:PyTorch CUDA 版本与系统驱动不兼容。常见于 Ubuntu 22.04 + NVIDIA 驱动 535,但装了
torch==2.1.2+cu121(应为cu118)。 - 解决:
- 查驱动版本:
nvidia-smi,看右上角 “CUDA Version: 11.8”; - 查 PyTorch 版本:
python -c "import torch; print(torch.version.cuda)",应输出11.8; - 若不一致,卸载重装:
pip uninstall torch torchvision && pip install torch==2.1.2+cu118 torchvision==0.16.2+cu118 --index-url https://download.pytorch.org/whl/cu118。
- 查驱动版本:
4.5 现象:Windows 上启动报OSError: [WinError 126] 找不到指定的模块,且llama_cpp._llama_cpp加载失败
- 原因:Windows 缺少 Visual C++ 运行库,或
llama-cpp-python编译时未链接vcruntime140.dll。 - 解决:
- 下载安装 Microsoft Visual C++ 2015-2022 Redistributable (x64) ;
- 重装
llama-cpp-python并强制指定编译器:pip uninstall -y llama-cpp-python set DISTUTILS_USE_SDK=1 set MSSdk=1 pip install llama-cpp-python==0.2.79 --force-reinstall --no-deps --verbose
5. 验证 Web UI 是否真正跑通:用 curl 模拟请求 + 检查 token 流式输出
装完不是终点,验证才是。很多人以为页面能打开就 OK,结果实际调用时发现流式响应(streaming)失效、history 无法保存、system prompt 被忽略——这些只有通过真实 API 请求才能暴露。我们用最原始的curl,绕过浏览器缓存和前端 JS,直击后端逻辑。
5.1 发送标准 chat completion 请求(非流式)
curl -X POST "http://localhost:7860/v1/chat/completions" \ -H "Content-Type: application/json" \ -d '{ "model": "deepseek-r1", "messages": [ {"role": "system", "content": "你是一个严谨的AI助手,只回答事实,不编造。"}, {"role": "user", "content": "Deepseek-R1 的上下文长度是多少?"} ], "temperature": 0.1, "max_tokens": 128 }'✅预期响应:返回 JSON,choices[0].message.content应为"Deepseek-R1 的上下文长度为 32768 个 token。"(或类似准确回答)。
❌若失败:检查messages数组是否为空、model字段是否与启动时--model-path的 basename 一致(Page Assist 用此字段做路由)。
5.2 验证流式响应(streaming)——这是 Web UI 实时打字效果的基础
Web UI 的“打字机效果”依赖 SSE(Server-Sent Events)。用curl模拟:
curl -X POST "http://localhost:7860/v1/chat/completions" \ -H "Content-Type: application/json" \ -d '{ "model": "deepseek-r1", "messages": [{"role": "user", "content": "用 Python 写一个快速排序"}], "stream": true }' \ --no-buffer✅预期行为:立即开始输出多行data: {...},每行是一个delta.content片段,如:
data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","created":171...,"choices":[{"delta":{"content":"def"},"index":0}]} data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","created":171...,"choices":[{"delta":{"content":" quicksort"},"index":0}]} ...✅关键指标:首 token 延迟(Time to First Token, TTFT)应 < 1.5s(RTX 4090),且每秒输出 ≥ 15 tokens。
❌若无输出或卡住:检查启动时是否漏了--n-gpu-layers(CPU 模式下 streaming 会阻塞),或--ctx-size是否过大导致初始化超时。
5.3 检查 history 与 session 状态(Web UI 的核心价值)
Page Assist 的/v1/chat/completions支持session_id,用于维持对话状态。测试连续两次请求:
# 第一次:创建 session curl -X POST "http://localhost:7860/v1/chat/completions" \ -H "Content-Type: application/json" \ -d '{ "model": "deepseek-r1", "messages": [{"role": "user", "content": "记住:我的名字是张三"}], "session_id": "test-session-001" }' # 第二次:延续同一 session curl -X POST "http://localhost:7860/v1/chat/completions" \ -H "Content-Type: application/json" \ -d '{ "model": "deepseek-r1", "messages": [{"role": "user", "content": "我叫什么?"}], "session_id": "test-session-001" }'✅预期:第二次响应中content应包含"张三"。这证明 Page Assist 的内存 session 管理正常,Web UI 的“记住上下文”功能可用。
⚠️注意:session_id是字符串,不是数字;不同 session_id 之间完全隔离。
5.4 最后一道防线:用 Python 脚本自动化验证全流程
把以上三步写成verify_pageassist.py,每次部署新环境前跑一遍,5 秒内给出结论:
# verify_pageassist.py import requests import time BASE_URL = "http://localhost:7860" def test_non_stream(): r = requests.post(f"{BASE_URL}/v1/chat/completions", json={ "model": "deepseek-r1", "messages": [{"role": "user", "content": "1+1="}], "temperature": 0.01 }) return r.status_code == 200 and "2" in r.json()["choices"][0]["message"]["content"] def test_stream(): r = requests.post(f"{BASE_URL}/v1/chat/completions", json={ "model": "deepseek-r1", "messages": [{"role": "user", "content": "A"}], "stream": True }, stream=True) if r.status_code != 200: return False # 检查是否收到至少 3 个 data: 行 lines = [line for line in r.iter_lines() if line.startswith(b'data:')] return len(lines) >= 3 def test_session(): # 第一次 r1 = requests.post(f"{BASE_URL}/v1/chat/completions", json={ "model": "deepseek-r1", "messages": [{"role": "user", "content": "我的代号是Alpha"}], "session_id": "verify-test" }) # 第二次 r2 = requests.post(f"{BASE_URL}/v1/chat/completions", json={ "model": "deepseek-r1", "messages": [{"role": "user", "content": "我的代号?"}], "session_id": "verify-test" }) return r1.status_code == 200 and r2.status_code == 200 and "Alpha" in r2.json()["choices"][0]["message"]["content"] if __name__ == "__main__": print("🔍 Testing non-streaming...") assert test_non_stream(), "Non-streaming failed" print("✅ Non-streaming OK") print("🔍 Testing streaming...") assert test_stream(), "Streaming failed" print("✅ Streaming OK") print("🔍 Testing session state...") assert test_session(), "Session state failed" print("✅ Session state OK") print("\n🎉 All tests passed! Deepseek Page Assist is ready.")运行python verify_pageassist.py,若输出🎉 All tests passed!,说明从模型加载、API 路由、流式响应到 session 管理,整条链路已打通。这才是真正“能用”的标志。
从那以后我每次部署新环境,不管多晚,都强制跑一遍这个脚本——它比盯着浏览器点十次“发送”更可靠。因为 Web UI 的表象太容易骗人,而 curl 和 Python 脚本不会说谎。希望帮到你。
本文还有配套的精品资源,点击获取