localaiforum
登录
指南 › 运行与服务

服务一个 OpenAI 兼容端点

跑一次引擎、在聊天窗口里对话、你有一个玩具。以人人已经在说的形状经 HTTP 服务它、你就有基础设施:编辑器、UI、智能体和你自己的脚本都能驱动同一个本地模型。本页搭起本地端点、然后覆盖流式、SDK、安全和热加载。

为什么 OpenAI 形状赢了

chat-completions 请求格式——模型名、一列 {role, content} 消息、几个旋钮——成为事实标准、因为每个工具作者都先为它写了客户端。无论你怎么看那家公司、形状是中立的:它只是 POST 上的 JSON。实际后果:任何模仿它的本地服务器立刻兼容一大堆积压的现有软件。你的引擎选择和客户端选择成为独立决策(见 引擎)。

一分钟跑起 llama-server

llama-server -m model.gguf -c 8192 --port 8080
# UI 在 http://127.0.0.1:8080 — API 在 /v1/chat/completions

一条带注解的请求:

curl http://127.0.0.1:8080/v1/chat/completions -H "Content-Type: application/json" -d '{"model":"model","messages":[{"role":"user","content":"Why run local? One sentence."}],"temperature":0.7,"max_tokens":60}'
  • model——llama-server 服务你启动的任何东西;该字段常被忽略、但发个正常的名字。
  • messages——整个对话、系统提示词在前;无状态服务器、历史由你持有。
  • max_tokens——封顶回复;保护你免受失控生成。

响应(裁剪过)带着回答加上你做零成本调试会想要的词元账目:

{
  "choices": [
    { "message": { "role": "assistant", "content": "No accounts, no rate limits, and your data never leaves the machine." } }
  ],
  "usage": { "prompt_tokens": 14, "completion_tokens": 15 }
}

usage 是你了解提示词实际花掉多少上下文的途径——在怪模型“忘事”之前查它(见 词元)。

流式

加 "stream": true、服务器切换到 server-sent events:换行分隔的 data: 块、每块带一个小增量、以哨兵结尾。

data: {"choices":[{"delta":{"content":"No "}}]}
data: {"choices":[{"delta":{"content":"accounts"}}]}
data: [DONE]

客户端:累积 delta.content 直到 [DONE] 行。流式不让生成更快——它让等待可容忍、对聊天 UX 是同一回事(见 速度)。

Ollama:一个服务、两套 API

Ollama 的原生 API 稍富——按请求选项和模型生命周期控制:

curl http://127.0.0.1:11434/api/chat -d '{"model":"qwen3:8b","messages":[{"role":"user","content":"hi"}],"stream":false,"keep_alive":-1}'

它也在 /v1/chat/completions 服务 OpenAI 兼容路由、所以 OpenAI 形状的客户端无需改动就能对 Ollama 工作。想要 keep_alive 或按请求引擎选项时用原生 API;其余一切用 /v1。

GPU 服务器用 vLLM

vllm serve Qwen/Qwen3-8B --max-model-len 16384 --port 8000

vLLM 拉 safetensors 权重、加载一次、并在底下以连续批处理服务同一 OpenAI 形状——并发用户一出现就是对的工具(见 并发)。它要 NVIDIA 显存和一块真 GPU;单用户桌面别费劲。

把官方 SDK 指向 localhost

官方 OpenAI 库只是 HTTP 客户端;换掉 base URL、API 密钥字段就成了装饰:

from openai import OpenAI

client = OpenAI(base_url="http://127.0.0.1:8080/v1", api_key="local")
r = client.chat.completions.create(
    model="qwen3-8b",
    messages=[{"role": "user", "content": "Why run local?"}],
)
print(r.choices[0].message.content)
import OpenAI from "openai";

const client = new OpenAI({ baseURL: "http://127.0.0.1:11434/v1", apiKey: "ollama" });
const r = await client.chat.completions.create({
  model: "qwen3:8b",
  messages: [{ role: "user", content: "Why run local?" }],
});

除非服务器配置了密钥、任何字符串都行。这个 base-URL 替换就是每个“兼容本地模型”工具背后的全部诀窍。

这解锁了什么

  • 编辑器和聊天 UI——见 UI 与集成。
  • 你自己的应用:你自己后端后面的本地模型、零每词元成本。
  • 带保证 schema 的脚本化流水线——见 结构化输出。
  • 调用工具并迭代的智能体循环——见 智能体。
  • 本论坛的游戏角:国际象棋和 janggi 智能体就是像上面的 curl 一样打本地 chat-completions 端点对弈的。

锁门

模型服务器对任何够得着端口的人是一台免费 LLM。默认是安全的——llama-server 和 Ollama 绑 127.0.0.1——在笔记本上保持这样。要在局域网暴露:设 API 密钥(llama-server 和 vLLM 的 --api-key、以及前面任何 UI 里的认证)、并偏爱反向代理做 TLS。绝不无认证绑 0.0.0.0:网络上任何人都能烧你的 GPU、填你的上下文、探你的设置。

保持热态

冷加载——权重从磁盘进显存——花掉数秒到数十秒的 TTFT。llama-server 和 vLLM 启动时加载并保持驻留、所以只有第一个请求付费。Ollama 在 keep_alive(默认 ~5 分钟)后卸载:发 "keep_alive": -1 无限期持有模型、或 0 在一阵突发后立即释放显存。如果你的设置“起初慢、之后好”、那是冷加载不是慢模型——而负载之下、加载风暴是真实的失败模式(见 并发)。

相关: 并发 · UI 与集成 · 引擎 · 结构化输出