无图形界面服务器用 Codex 终端连接本地部署的 DeepSeek
在只有 SSH 登录、没有图形界面、没有 root 权限的集群服务器上,如何让 Codex 终端接入本地部署的 DeepSeek 模型?本文给出完整方案:先在计算节点上用 llama.cpp 部署 DeepSeek 推理服务,再通过协议转换代理,让 Codex CLI 连接到该服务。
一、方案原理
整个方案由三个部分组成:
1. 推理服务端:在服务器节点上用 llama.cpp 加载 DeepSeek 的 GGUF 模型,对外提供 OpenAI 兼容的 Chat Completions 接口。
2. 协议转换代理:Codex CLI 新版本使用 Responses API,而 llama.cpp 只支持 Chat Completions API。两者协议不同,需要一个中间代理做转换。本文使用 codex-relay。
3. Codex 终端:在你的登录节点或本地电脑上运行 Codex CLI,通过代理访问推理服务。
数据流向:Codex 终端 → codex-relay 代理 → llama.cpp 推理服务 → DeepSeek 模型
二、准备工作
硬件要求:CPU 至少 8 核,内存 16GB 以上,存储预留 20GB。本文以 48 核 CPU、128GB 内存节点为例。
软件要求:系统 GCC 版本低于 8.2 时需自行编译 GCC 9.5。CMake 版本需 3.14 以上。Git 可用。
网络要求:运行 Codex 的机器能够访问推理服务所在节点的 IP 和端口。集群内部网络通常互通。
三、部署本地 DeepSeek 推理服务
3.1 编译 llama.cpp
克隆源码并配置 CMake。纯 CPU 版本不需要开启 CUDA,避免依赖显卡驱动。
cd ~/llama.cpprm -rf build-cpucmake -B build-cpu -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_C_COMPILER=$HOME/software/gcc-9.5.0/install/bin/gcc \ -DCMAKE_CXX_COMPILER=$HOME/software/gcc-9.5.0/install/bin/g++ \ -DCMAKE_CXX_STANDARD=17 \ -DGGML_OPENMP=ONcmake --build build-cpu --config Release -j 48
编译成功后,可执行文件位于 build-cpu/bin/ 目录下。
3.2 下载 GGUF 模型
从 Hugging Face 或 ModelScope 下载 DeepSeek-R1-Distill-Qwen-7B-Q4_K_M.gguf,约 4.5GB。放置于 ~/models/ 目录。
ModelScope 下载命令示例:
mkdir -p ~/models && cd ~/models wget https://www.modelscope.cn/models/unsloth/DeepSeek-R1-Distill-Qwen-7B-GGUF/resolve/master/DeepSeek-R1-Distill-Qwen-7B-Q4_K_M.gguf
如果模型较大导致速度慢,可以换用 1.5B 或 3B 的蒸馏版模型,推理速度会明显提升。
3.3 启动 API 服务
使用 llama-server 启动服务,监听所有网卡,端口 8888,上下文 32768,线程数根据 CPU 核心数调整。
cd ~/llama.cpp/build-cpu/bin ./llama-server \ -m ~/models/DeepSeek-R1-Distill-Qwen-7B-Q4_K_M.gguf \ --host 0.0.0.0 \ --port 8888 \ -c 32768 \ -t 48 \ --alias deepseek-2-3
其中 --alias 参数给模型起一个简短的别名,方便后续 Codex 配置时使用。
启动日志出现 listening on http://0.0.0.0:8888 即表示成功。
建议使用 nohup 或 tmux 让服务在后台持续运行,避免关闭终端后服务中断:
nohup ./llama-server -m ~/models/DeepSeek-R1-Distill-Qwen-7B-Q4_K_M.gguf \ --host 0.0.0.0 --port 8888 -c 32768 -t 48 --alias deepseek-2-3 \ > ~/llama-server.log 2>&1 &
四、安装 Codex CLI
4.1 安装 Node.js
在 CentOS 7 等老旧系统上,直接安装高版本 Node.js 会遇到 GLIBC 版本不兼容的问题。推荐使用 conda 安装 Node.js,conda-forge 的版本专门为老系统编译,能避开这个问题。
conda activate open-webui conda install -c conda-forge nodejs -y
安装完成后验证:
which node node -v npm -v
正常情况下应输出 conda 环境下的 node 路径,版本为 v20.x,且不再报 GLIBC 错误。
4.2 安装 Codex CLI
npm install -g @openai/codex
验证安装:
codex --version
五、配置协议转换代理
5.1 为什么需要代理
Codex CLI v0.154.0 已不再支持 wire_api = "chat",只支持 wire_api = "responses"。而 llama.cpp 提供的是 Chat Completions 接口。两者协议不匹配,直接连接会失败。
codex-relay 的作用是把 Codex 发出的 Responses API 请求实时翻译成 Chat Completions 请求,再转发给 llama.cpp。
5.2 安装 codex-relay
pip install codex-relay
5.3 启动代理
codex-relay --upstream http://10.1.1.1:8888/v1 --api-key dummy --port 8080
参数说明:
--upstream:指向 llama.cpp 服务地址,注意参数名是 upstream 不是 base-url。
--api-key:llama.cpp 不需要认证,随便填一个非空值。
--port:代理监听端口,可自行修改。
代理同样建议用 nohup 或 tmux 放到后台运行:
nohup codex-relay --upstream http://10.1.1.1:8888/v1 \ --api-key dummy --port 8080 > ~/codex-relay.log 2>&1 &
六、配置 Codex 连接本地模型
6.1 编辑 config.toml
打开 ~/.codex/config.toml,写入以下内容:
model = "deepseek-2-3"model_provider = "local-ollama"model_catalog_json = "//.codex/models.json"[model_providers.local-ollama]name = "Local DeepSeek"base_url = "http://127.0.0.1:8080/v1"env_key = "OLLAMA_API_KEY"wire_api = "responses"requires_openai_auth = false
关键字段说明:
model:必须与 llama.cpp 启动时 --alias 指定的名称一致。
base_url:指向 codex-relay 代理地址,不是 llama.cpp 地址。
env_key:环境变量名,本地服务不需要认证,但字段不能为空。
wire_api:必须填 responses,新版 Codex 已不支持 chat。
requires_openai_auth:设为 false,避免发送 OpenAI 认证头。
6.2 配置模型元数据
Codex 需要知道模型的上下文窗口等元数据,否则会提示 Model metadata not found。在 ~/.codex/models.json 中添加模型条目。
可以用以下 Python 脚本,复制已有模型条目并改名为你的模型:
python - <<'PY'import jsonpath = "//.codex/models.json"with open(path) as f: data = json.load(f)new_model = data["models"][0].copy()new_model["slug"] = "deepseek-2-3"new_model["display_name"] = "Local DeepSeek"new_model["description"] = "Local llama.cpp DeepSeek model"data["models"].append(new_model)with open(path, "w") as f: json.dump(data, f, indent=2)print("done")PY
6.3 设置环境变量
把环境变量写入 ~/.bashrc,避免每次打开终端都要重新设置:
echo 'export OLLAMA_API_KEY="dummy"' >> ~/.bashrc source ~/.bashrc
6.4 启动测试
确保 llama.cpp 服务和 codex-relay 代理都在运行,然后启动 Codex:
conda activate open-webui codex
启动界面应显示 model: deepseek-2-3。输入一个简单问题测试,例如"写一个 Python 的 hello world"。
七、常见问题与排查
问题一:GLIBC 版本不兼容
现象:运行 node 时报错 version GLIBC_2.27 not found。
原因:nvm 安装的 Node.js 版本过高,依赖新版 GLIBC。
解决:改用 conda 安装的 Node.js。检查 ~/.bashrc 中是否加载了 nvm,将其注释掉,确保 conda 环境的 node 优先。
问题二:提示 OLLAMA_API_KEY 缺失
原因:环境变量没有设置。
解决:在 ~/.bashrc 中添加 export OLLAMA_API_KEY="dummy",然后执行 source ~/.bashrc。
问题三:wire_api = "chat" 不再支持
原因:Codex 新版本强制使用 Responses API。
解决:将 config.toml 中的 wire_api 改为 responses,并确保 codex-relay 代理正在运行。
问题四:连接超时或无法连接
排查步骤:
-
确认 llama.cpp 服务在运行:curl http://节点IP:8888/v1/models
-
确认 codex-relay 代理在运行:curl http://127.0.0.1:8080/v1/models
-
确认 config.toml 中 base_url 指向的是代理地址而非 llama.cpp 地址
-
确认防火墙放行了相关端口
问题五:响应速度很慢
原因:纯 CPU 推理 7B 模型,生成速度约 5 至 6 tokens/s。Codex 的系统提示词很长,首次响应可能需要几分钟。
解决:
-
确认 llama.cpp 是否在用 GPU,启动日志中查找 CUDA 或 offloaded 字样
-
换用更小的模型,如 1.5B 或 3B 蒸馏版
-
先用极短的问题测试,不要一上来就问复杂问题
问题六:startup issue 提示 bubblewrap 缺失
这是 Codex 沙箱功能的提示,不影响正常使用。可以忽略,也可以在有权限的情况下通过系统包管理器安装 bubblewrap。
八、完整流程速查
第一步:在计算节点上编译 llama.cpp 并启动服务
./llama-server -m ~/models/model.gguf --host 0.0.0.0 --port 8888 -c 32768 -t 48 --alias deepseek-2-3
第二步:在运行 Codex 的机器上启动代理
codex-relay --upstream http://节点IP:8888/v1 --api-key dummy --port 8080
第三步:配置 Codex
model = "deepseek-2-3"model_provider = "local-ollama"model_catalog_json = "~/.codex/models.json"[model_providers.local-ollama]base_url = "http://127.0.0.1:8080/v1"env_key = "OLLAMA_API_KEY"wire_api = "responses"requires_openai_auth = false
第四步:启动 Codex
conda activate open-webui codex
通过以上步骤,可以在无图形界面、无 root 权限的服务器上,用 Codex 终端连接本地部署的 DeepSeek 模型,实现代码辅助、文件分析等 AI 交互。整个过程完全依赖普通用户权限,适合在集群环境中使用。