在本地部署一套几乎免费的大模型环境1:用 Ollama + LiteLLM + Open WebUI 搭好基础环境并改到 TaoToken

发布时间:2026/10/3 19:27:59
在本地部署一套几乎免费的大模型环境1:用 Ollama + LiteLLM + Open WebUI 搭好基础环境并改到 TaoToken
1. 为什么本地跑大模型最后都绕不开一个统一网关很多人第一次接触大模型习惯直接调云端 API开箱即用确实爽。但项目一旦深入数据隐私、响应延迟、长期调用成本这三件事就会陆续冒出来。尤其是当你需要把内部代码库、业务文档喂给模型时数据离开内网这件事本身就让人不踏实。本地部署的价值就在这里模型权重在你自己的硬盘上推理过程在你自己的显卡上数据从输入到输出全程不出局域网。但本地部署不等于零成本。模型权重文件确实大多开源免费可要让它们跑起来硬件投入是实打实的。一个 7B 参数的模型FP16 精度下至少需要 14GB 显存4-bit 量化后也要 6GB 以上才能流畅。如果你想跑 14B 甚至更大消费级显卡往往捉襟见肘。再加上长时间推理的电费、环境依赖的维护时间这些都是隐性成本。所以我的思路很明确先用最朴素的方案把流程跑通再考虑优化。这套环境的目标是全本地化、开源、局域网内多终端可用、有类 ChatGPT 的界面、支持多模型切换和降级。组件选型上模型层用 Ollama它把模型管理、API 服务和命令行打包在一起安装简单对新手友好网关层用 LiteLLM对外统一暴露 OpenAI 格式的 API支持多平台切换和 failover前端层用 Open WebUI提供类 ChatGPT 的聊天界面支持多用户、RAG、联网搜索和多模态。数据流向很清晰用户请求 → Open WebUI → LiteLLM 网关 → Ollama API → 模型推理 → 返回结果。这套架构的好处是每一层都可以独立替换或扩展后面想加云端模型、加 Agent、加 RAG都只需要在 LiteLLM 的配置里动刀前端和模型层不用大改。我试过把这套东西拆开单独用Ollama 直接连 Open WebUI 也能跑但一旦你有两台机器、多个模型、需要主备切换没有网关层就会非常痛苦。LiteLLM 的model_name机制可以把多个部署归到同一个逻辑模型下按order优先级自动路由主节点挂了自动切备用这对 7×24 运行的环境来说几乎是刚需。另外这套环境还有一个隐藏好处它让你对模型服务这件事有了统一的抽象。不管底层是 Ollama、还是云端某个 OpenAI 兼容接口上层 Open WebUI 看到的永远是一个/v1/models列表和一个/v1/chat/completions端点。这种一致性在后续做自动化、做 Agent 编排时非常省心。2. TaoToken 前置把云端能力接进本地网关本地模型有它的边界。7B、14B 的模型在日常对话、单文件代码生成上够用但遇到复杂推理、长文档理解、多轮工具调用小模型的幻觉和逻辑断裂就会明显。这时候一个自然的做法是本地模型兜底日常请求复杂任务路由到云端更强的模型。LiteLLM 正好支持这种混合路由。TaoToken 在这里扮演的角色是云端模型接入层。它提供 OpenAI 兼容的 API 接口意味着你不需要为每个云端模型单独写适配代码只要在 LiteLLM 的model_list里加一条配置指定api_base和api_key就能把云端模型和本地 Ollama 模型放在同一个路由体系里。对 Open WebUI 来说它们都只是/v1/models里的一个条目。你需要先拿到两样东西API Key 和 Base URL。API Key 在控制台的 API Keys 页面生成Base URL 是https://taotoken.net/api。这两个值后面会写进 LiteLLM 的配置文件和 Open WebUI 的环境变量里。具体操作路径打开 https://taotoken.net/api-keys 登录后创建一个新的 Key复制保存。然后打开 https://taotoken.net/doc 确认一下当前的接口规范主要是确认/v1/chat/completions和/v1/models的路径前缀。TaoToken 的接口是 OpenAI 兼容的所以 LiteLLM 里用openai/前缀的 provider 就能直接对接。这里有个细节要注意LiteLLM 配置里api_base填的是https://taotoken.net/api不要带/v1因为 LiteLLM 的 openai provider 会自动拼接/v1/chat/completions。如果你填成https://taotoken.net/api/v1最终请求路径会变成/api/v1/v1/chat/completions直接 404。这个坑我在第一次配置时踩过日志里看到路径重复才反应过来。另外TaoToken 的 Key 和 LiteLLM 自己的master_key是两回事。master_key是 LiteLLM 网关对外的鉴权密钥Open WebUI 用它来访问 LiteLLMTaoToken 的 Key 是 LiteLLM 访问云端时用的凭证。两者不要混用配置时各归各的位置。如果你只是想先验证本地环境能不能跑通可以暂时不加 TaoToken 的配置等本地 Ollama LiteLLM Open WebUI 闭环验证完再往model_list里追加云端条目。这样排障时变量更少出问题容易定位。3. 可复制配置Ollama、LiteLLM、Open WebUI 三件套这一节给出完整的配置文件你可以直接复制修改。假设你有两台机器Windows 机器 IP 是10.25.1.58Mac mini IP 是10.25.1.71。Windows 上跑主力模型Mac 上跑网关和前端同时作为备用推理节点。先看 Windows 上的 Ollama 配置。安装完 Ollama 后需要让它监听局域网。设置环境变量OLLAMA_HOST0.0.0.0然后重启 Ollama 服务。防火墙放行 11434 端口netsh advfirewall firewall add rule nameOllama 11434 dirin actionallow protocolTCP localport11434然后为不同模型创建独立的 Modelfile控制上下文长度和 GPU 层数。Windows 上主力编码模型用qwen2.5-coder:14b上下文限制在 8192 保护 12G 显存FROM qwen2.5-coder:14b PARAMETER num_ctx 8192 PARAMETER num_gpu 99 SYSTEM 你是资深 Python 开发专家。请严格遵循 PEP8 规范。 在生成代码时必须包含必要的注释、错误处理和类型提示。 通用对话模型用qwen3.5:9b-q4_K_M上下文可以开到 131072FROM qwen3.5:9b-q4_K_M PARAMETER num_ctx 131072 PARAMETER num_gpu 99构建自定义模型ollama create qwen2.5-coder:14b -f Modelfile ollama create qwen3.5-long -f Modelfile-qwen3.5-9bMac 上的 Ollama 配置类似备用编码模型用qwen2.5-coder:7b上下文 8192FROM qwen2.5-coder:7b PARAMETER num_ctx 8192 PARAMETER num_gpu 99 SYSTEM 你是资深 Python 开发专家。请严格遵循 PEP8 规范。 构建并运行ollama create qwen2.5-coder:7b-8k -f Modelfile ollama run qwen2.5-coder:7b-8kMac 上同样设置OLLAMA_HOST0.0.0.0写入~/.zshrc后重启 Ollama。接下来是 LiteLLM 的config.yaml这是整个网关的核心。它定义了模型列表、路由策略和降级规则general_settings: master_key: sk-litellm-local-你的密钥串 model_list: - model_name: local-coder-vision litellm_params: model: ollama_chat/qwen3.5-long api_base: http://10.25.1.58:11434 timeout: 30 num_retries: 1 model_info: order: 0 - model_name: local-coder litellm_params: model: ollama_chat/qwen2.5-coder:14b api_base: http://10.25.1.58:11434 timeout: 30 num_retries: 1 model_info: order: 1 - model_name: local-coder litellm_params: model: ollama_chat/qwen2.5-coder:7b-8k api_base: http://10.25.1.71:11434 timeout: 30 num_retries: 1 model_info: order: 2 - model_name: cloud-reasoner litellm_params: model: openai/你的云端模型ID api_base: https://taotoken.net/api api_key: sk-你的TaoToken密钥 timeout: 60 num_retries: 2 router_settings: fallbacks: - local-coder: - local-coder timeout: 30 num_retries: 1 allowed_fails: 2 cooldown_time: 30 litellm_settings: drop_params: true set_verbose: false log_level: WARNING这里的关键点model_name是 Open WebUI 里看到的模型名litellm_params.model是实际调用的后端模型。两个local-coder条目共享同一个model_nameorder越小优先级越高Windows 14B 是主Mac 7B 是备。local-coder-vision独立成一个模型名不会参与编码模型的 fallback。启动 LiteLLMlitellm --config config.yaml --port 4000 --host 0.0.0.0后台运行nohup litellm --config config.yaml --port 4000 --host 0.0.0.0 litellm.log 21 最后是 Open WebUI 的docker-compose.ymlversion: 3.8 services: openwebui: image: ghcr.io/open-webui/open-webui:main container_name: openwebui ports: - 3001:8080 volumes: - openwebui-data:/app/backend/data environment: - OPENAI_API_BASE_URLhttp://host.docker.internal:4000/v1 - OPENAI_API_KEYsk-litellm-local-你的密钥串 - ENABLE_OLLAMA_APIfalse - WEBUI_AUTHfalse - CORS_ALLOW_ORIGIN* extra_hosts: - host.docker.internal:host-gateway restart: unless-stopped volumes: openwebui-data:OPENAI_API_BASE_URL指向 LiteLLM 的/v1端点OPENAI_API_KEY填 LiteLLM 的master_key。ENABLE_OLLAMA_APIfalse让 Open WebUI 不要自己管 Ollama统一走 LiteLLM。启动docker compose up -d4. 验证请求从 curl 到界面确认每一层都通配置写完接下来是验证。验证的顺序应该从底层往上走先确认 Ollama 能响应再确认 LiteLLM 能路由最后确认 Open WebUI 能对话。第一步在 Mac 上 curl Windows 的 Ollamacurl http://10.25.1.58:11434看到Ollama is running说明网络和防火墙都没问题。如果超时检查 Windows 防火墙规则是否生效以及OLLAMA_HOST是否真的重启后生效。第二步验证 LiteLLM 的模型列表curl http://localhost:4000/v1/models \ -H Authorization: Bearer sk-litellm-local-你的密钥串返回的 JSON 里应该能看到local-coder和local-coder-vision。如果只有其中一个检查config.yaml的缩进YAML 对空格敏感model_list下的每个条目缩进必须一致。第三步发一个实际的对话请求验证路由curl http://localhost:4000/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-litellm-local-你的密钥串 \ -d { model: local-coder, messages: [{role: user, content: 用 Python 写一个快速排序}], max_tokens: 200 }观察 LiteLLM 的日志应该显示请求打到了http://10.25.1.58:11434模型是qwen2.5-coder:14b。然后关掉 Windows 的 Ollama再发一次同样的请求日志应该切到http://10.25.1.71:11434模型变成qwen2.5-coder:7b-8k。这就是 fallback 生效的证据。第四步验证 TaoToken 云端接入。如果你在model_list里加了cloud-reasoner发一个请求curl http://localhost:4000/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-litellm-local-你的密钥串 \ -d { model: cloud-reasoner, messages: [{role: user, content: 解释一下 Transformer 的注意力机制}], max_tokens: 300 }如果返回正常说明 LiteLLM 成功用 TaoToken 的 Key 调用了云端接口。如果报 401检查api_key是否填对如果报 404检查api_base是否多了/v1。第五步打开浏览器访问http://10.25.1.71:3001。如果WEBUI_AUTHfalse直接进主页。顶部模型下拉里应该能看到local-coder和local-coder-vision。选local-coder发一句print(123)看 LiteLLM 日志确认走了 Windows 14B。然后关 Windows Ollama再发一次确认切到 Mac 7B。到这里整条链路就验证完了Open WebUI → LiteLLM → Ollama本地或 TaoToken云端→ 返回结果。每一层都有明确的日志和可观测的切换行为。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth配置过程中最容易遇到的几个报错这里逐一对照。401 Unauthorized。这个报错通常出现在两个位置Open WebUI 访问 LiteLLM 时或者 LiteLLM 访问 TaoToken 时。如果是前者检查docker-compose.yml里的OPENAI_API_KEY是否和config.yaml里的master_key完全一致包括sk-前缀。如果是后者检查model_list里云端条目的api_key是否填了正确的 TaoToken Key。还有一种情况是 Key 复制时带了空格YAML 里字符串前后的空格会被保留导致鉴权失败。local proxy failed。这个报错一般出现在 LiteLLM 启动阶段提示无法绑定端口或配置文件解析失败。先检查 4000 端口是否被占用lsof -i :4000。如果被占用换一个端口同时更新 Open WebUI 的OPENAI_API_BASE_URL。如果是配置解析失败用python -c import yaml; yaml.safe_load(open(config.yaml))验证 YAML 语法重点检查缩进和冒号后的空格。reading choices 相关报错。这个通常出现在 LiteLLM 转发请求后解析云端返回时出错。常见原因是api_base路径不对导致返回的不是标准的 OpenAI 格式 JSON。检查api_base是否填成https://taotoken.net/api不要带/v1。另外检查model字段是否填了正确的模型 ID如果模型 ID 不存在云端可能返回错误结构LiteLLM 解析choices字段时就会报错。OAuth 相关报错。如果你在 Open WebUI 里开启了WEBUI_AUTHtrue首次访问会要求注册管理员账号。如果注册后登录报 OAuth 错误检查CORS_ALLOW_ORIGIN是否设置正确。局域网访问时如果 Open WebUI 的地址和 LiteLLM 的地址跨域浏览器可能会拦截。设置CORS_ALLOW_ORIGIN*可以临时绕过生产环境建议改成具体域名。模型列表为空。Open WebUI 顶部下拉里看不到任何模型说明它没能从 LiteLLM 拉到/v1/models。检查OPENAI_API_BASE_URL是否指向http://host.docker.internal:4000/v1注意 Mac 上 Docker 访问宿主机必须用host.docker.internal不能用localhost。另外确认extra_hosts里加了host.docker.internal:host-gateway否则容器内解析不了这个域名。fallback 不生效。关掉 Windows Ollama 后请求没有切到 Mac而是直接报错。检查router_settings.fallbacks的格式它应该是一个列表每个元素是一个字典键是model_name值是该模型名下的备用列表。另外确认两个local-coder条目的model_name完全一致大小写和连字符都不能差。显存溢出 OOM。模型加载到一半崩溃或者推理时突然退出。降低num_ctx或者换更低精度的量化版本。Windows 14B 在 12G 显存上跑 8192 上下文是安全的如果你开到 16384 就可能溢出。用nvidia-smi --query-gpumemory.used,memory.total --formatcsv -l 1实时监控显存。6. 后续扩展与 CTA基础环境跑通后这套架构的扩展空间很大。你可以在 LiteLLM 的model_list里继续追加云端模型按order做优先级路由可以在 Open WebUI 里开启 RAG把本地文档喂给模型也可以在前面加一层 Agent 框架用 LiteLLM 的统一接口做工具调用。如果你想把云端能力正式接进来建议先去 https://taotoken.net/api-keys 生成一个专用 Key然后在 LiteLLM 配置里加一条cloud-reasoner条目。接口规范参考 https://taotoken.net/doc 确认路径和参数格式。验证云端模型是否可用可以直接在模型对话页面发一条测试请求https://taotoken.net/model-chat 。对于长期跑编码任务或 Agent 的场景可以考虑 Coding Plan它更适合高频、长上下文的调用模式https://taotoken.net/coding-plan 。日常管理和 Key 轮换在控制台完成https://taotoken.net/console 。如果你用 Claude Code 或类似的编码工具接入文档在这里https://taotoken.net/doc 。整套环境的核心思路是本地模型负责日常和隐私敏感任务云端模型负责复杂推理和长上下文LiteLLM 做统一路由和降级Open WebUI 提供统一界面。每一层都可以独立替换不会因为某个组件升级而牵一发动全身。先把这条链路跑通后面的优化和扩展都是在这个基础上做加法。