mistral.rs HTTP 服务器文本补全(/v1/completions)实战指南
【免费下载链接】mistral.rsFast, flexible LLM inference项目地址: https://gitcode.com/GitHub_Trending/mi/mistral.rs
本文以 mistral.rs 仓库中可运行的 HTTP 服务器示例completion为主线,讲解如何基于 OpenAI 兼容的/v1/completions端点对纯文本模型发起补全请求。你将掌握从启动serve服务器、使用openaiPython 客户端交互式调用,到理解请求参数在服务端如何被解析为采样配置的完整链路,并学会排查与调试 HTTP 请求/响应。
示例概览:一个可运行的文本补全客户端
docs/src/content/docs/examples/server/completion.md文档(由 render_examples.py 从源码示例自动生成)对应仓库中的 examples/server/completion.py 文件。它是一个最小但完整的 HTTP 服务器客户端示例,演示了:
- 使用官方
openaiPython SDK 连接 mistral.rs 的 OpenAI 兼容 API; - 通过
client.completions.create()调用文本补全端点; - 在 REPL 循环中不断读取用户输入并打印模型输出;
- 提供可选的 httpx 请求/响应日志钩子,用于调试网络层细节。
该示例假设模型已通过mistralrs serve命令加载,并监听在localhost:1234上——这正是mistralrsHTTP 服务器的默认端口。
第一步:启动文本补全服务器
示例客户端连接http://localhost:1234/v1/,对应服务器端的默认配置。mistralrs-cli的serve子命令负责加载模型并启动 HTTP 服务,其默认端口定义为 1234、绑定地址为0.0.0.0,见 ServerOptions 定义。
# 以交互式模型源启动(-i),并指定端口(默认已是 1234) mistralrs serve --port 1234 -i --model-id <模型ID>对于本地 GGUF 文件,可以改为显式指定量化文件:
mistralrs serve --port 1234 -i -f <模型.gguf> --model-id <模型ID>服务启动后,run_server会打印 API 面信息(见 serve.rs 的 log_api_surfaces),其中包含OpenAI-compatible API: http://localhost:1234/v1与Swagger UI docs: http://localhost:1234/docs。此时/v1/completions端点即已就绪。
注意:
/v1/completions是 OpenAI 的旧版文本补全(Text Completion)端点,只接收纯文本prompt而不走 Chat 模板。mistralrs同时提供/v1/chat/completions(对话补全)与/v1/completions(文本补全),本示例聚焦后者。
完整示例代码解读
以下是 examples/server/completion.py 的完整内容,它也是本文档的核心:
from openai import OpenAI import httpx import textwrap import json def log_response(response: httpx.Response): request = response.request print(f"Request: {request.method} {request.url}") print(" Headers:") for key, value in request.headers.items(): if key.lower() == "authorization": value = "[...]" if key.lower() == "cookie": value = value.split("=")[0] + "=..." print(f" {key}: {value}") print(" Body:") try: request_body = json.loads(request.content) print(textwrap.indent(json.dumps(request_body, indent=2), " ")) except json.JSONDecodeError: print(textwrap.indent(request.content.decode(), " ")) print(f"Response: status_code={response.status_code}") print(" Headers:") for key, value in response.headers.items(): if key.lower() == "set-cookie": value = value.split("=")[0] + "=..." print(f" {key}: {value}") client = OpenAI(api_key="foobar", base_url="http://localhost:1234/v1/") # Enable this to log requests and responses # client._client = httpx.Client( # event_hooks={"request": [print], "response": [log_response]} # ) while True: prompt = input(">>> ") completion = client.completions.create( model="default", prompt=prompt, max_tokens=256, frequency_penalty=1.0, top_p=0.1, temperature=0, ) resp = completion.choices[0].text print(resp)客户端初始化与model="default"
client = OpenAI(api_key="foobar", base_url="http://localhost:1234/v1/")api_key可以是任意占位符(如"foobar"),因为 mistral.rs 本地服务器不校验密钥,只要求请求带上 Authorization 头以保持 OpenAI 协议兼容;base_url必须指向服务器的/v1/前缀,客户端后续所有路径(如/v1/completions)都基于它拼接。
请求中的model="default"是一个约定值:在 CompletionRequest 结构体 中,model字段的 serde 默认值就是"default",它表示"使用当前唯一加载的模型"。服务端在 parse_request 中,当model == "default"时将model_id置为None,即不按模型名路由、直接命中已加载的默认模型。
循环调用与采样参数
主循环每次读取一行用户输入,调用client.completions.create(...),并从completion.choices[0].text取出生成的文本打印。这里传入的四个采样参数在服务端各有对应实现(见下文"请求参数与采样语义"一节):
max_tokens=256:限制生成的最大 token 数;frequency_penalty=1.0:按 token 出现频率施加惩罚,抑制重复;top_p=0.1:核采样,只从累计概率质量前 10% 的 token 中采样;temperature=0:贪心解码,输出确定性最强。
可选的 HTTP 调试钩子
示例中注释掉的client._client = httpx.Client(...)通过 httpx 的event_hooks在请求发出前打印请求行,在响应返回后调用log_response打印完整的请求/响应头与请求体。log_response中做了两类隐私处理:
authorization头一律替换为[...],避免泄露 api_key;cookie与set-cookie只保留key=...前缀,避免打印完整 Cookie 值。
打开这组钩子后,你可以直观看到 SDK 实际发送的 JSON 请求体,以及服务器返回的状态码、content-type等头信息,非常适合排查参数未生效或网络异常的问题。
请求参数与采样语义:从 HTTP 到引擎
/v1/completions的请求体由 CompletionRequest 结构体 定义。除了示例中使用的四个参数,它还支持 OpenAI 标准的完整参数集以及 mistral.rs 的扩展字段:
OpenAI 标准字段
| 字段 | 类型 | 说明 |
|---|---|---|
model | String | 模型 ID,默认"default"(命中唯一加载的模型) |
prompt | String | 输入提示文本(必填) |
max_tokens | usize | 最大生成 token 数,别名max_completion_tokens;服务端校验max_tokens == 0会直接报错(见 completions.rs 校验逻辑) |
temperature | f64 | 采样温度,越高越随机 |
top_p | f64 | 核采样概率阈值 |
frequency_penalty | f32 | 按频率惩罚已出现 token,正值抑制重复 |
presence_penalty | f32 | 惩罚已出现过的 token(无论频率),正值鼓励转向新话题 |
logit_bias | HashMap<u32, f32> | 采样前对指定 token ID 的 logits 添加偏置 |
logprobs | usize | 返回该数量个最可能 token 的 log 概率 |
n(n_choices) | usize | 生成多少个候选补全,默认 1 |
stop(stop_seqs) | String | [String] | 停止序列,命中即终止生成 |
echo(echo_prompt) | bool | 是否在补全文本前回显 prompt,默认 false |
suffix | String | 追加在补全之后的文本 |
best_of | usize | 服务端生成多个候选并取最优(服务端将其透传进RequestMessage::Completion) |
seed | u64 | 固定随机种子,使请求级采样可复现 |
ignore_eos | bool | 忽略模型 EOS token,仅受显式 stop 与 token 上限约束 |
stream | bool | 是否以 SSE 流式返回,默认 false |
user | String | 透传的用户标识(服务端忽略) |
mistral.rs 扩展字段
| 字段 | 类型 | 说明 |
|---|---|---|
top_k | usize | 仅从概率最高的 k 个 token 中采样 |
min_p | f64 | 丢弃概率低于"最高 token 概率 × min_p"的 token |
repetition_penalty | f32 | 乘法式重复惩罚,1.0 表示关闭 |
grammar | object | 约束输出:regex、json_schema、lark或llguidance四种语法(对应 Constraint 枚举映射) |
dry_multiplier/dry_base/dry_allowed_length/dry_sequence_breakers | — | DRY 重复惩罚采样器参数,由 get_dry_sampling_params 组装为DrySamplingParams |
truncate_sequence | bool | 输入超过模型上下文长度时截断而非报错 |
tools/tool_choice | — | 供工具调用使用,文本补全端点同样透传 |
服务端 parse_request 将上述字段逐一映射到内部的NormalRequest与SamplingParams:temperature、top_k、top_p、min_p、top_n_logprobs、frequency_penalty、presence_penalty、repetition_penalty、max_len、stop_toks、logits_bias、n_choices等被原样传入采样器;prompt、echo_prompt、best_of则装入RequestMessage::Completion。这意味着你在 HTTP 层看到的每个采样参数,最终都会精确作用于引擎的采样过程。
服务端处理流程与流式响应
路由与响应类型
/v1/completions的处理器是 completions 函数,流程为:
- 反序列化请求体(JSON 解析失败返回
ValidationError); - 调用
resolve_lora_adapter_model解析 LoRA adapter 覆盖(若有); - 调用
parse_request转换为内部请求并发送给引擎(send_request_with_model); - 根据
stream字段分流:- 非流式:走
process_non_streaming_response,等引擎产出Response::CompletionDone后包装为CompletionResponder::Json返回; - 流式:构建
CompletionStreamer,以 SSE(Server-Sent Events)逐 chunk 推送,结束时发送data: [DONE]事件。
- 非流式:走
响应统一由CompletionResponder枚举承载(见 completion_core.rs),包括Json(完整响应)、Sse(流式)、ModelError、InternalError、ValidationError五种形态,其IntoResponse实现(completions.rs)负责把内部错误翻译为 OpenAI 风格的 JSON 错误响应。
流式 chunk 与错误事件
流式模式下,CompletionStreamer 的 poll_next 每次从通道收到Response::CompletionChunk就将其序列化为一条 SSE 事件;当所有choices的finish_reason都已就绪时进入DoneState::SendingDone,推送[DONE]结束标记。期间若发生模型错误、校验错误或内部错误,也会以 OpenAI 兼容的错误事件形式注入流中,而非直接断开连接。
流式响应支持两个扩展钩子:
CompletionOnChunkCallback:在 chunk 发送前回调,可用于内容过滤、改写或日志(例如 completions.rs 中展示的用法);CompletionOnDoneCallback:流结束后收到全部 chunks,适合做统计与分析。
非流式响应体中,usage字段由 CompletionUsageResponse 定义,除 OpenAI 标准的prompt_tokens、completion_tokens、total_tokens外,还额外包含cached_tokens(前缀缓存命中的 token 数)以及avg_tok_per_sec、total_time_sec等吞吐统计字段——这些是 mistral.rs 在兼容层之上提供的性能观测能力。
其他调用方式
使用 curl 一次性调用
不依赖任何 Python 依赖即可验证端点:
curl http://localhost:1234/v1/completions \ -H "Content-Type: application/json" \ -d '{ "model": "default", "prompt": "The capital of France is", "max_tokens": 32, "temperature": 0 }'流式调用
curl -N http://localhost:1234/v1/completions \ -H "Content-Type: application/json" \ -d '{ "model": "default", "prompt": "Once upon a time", "max_tokens": 64, "stream": true }'-N禁用 curl 缓冲,可以实时看到 SSE 事件流,最后一行是data: [DONE]。
小结
completion示例演示了 mistral.rs HTTP 服务器最基础的文本补全路径:serve启动 OpenAI 兼容服务 → SDK 以model="default"命中已加载模型 → 采样参数经parse_request映射进引擎。在它之上,你还可以进一步组合stop停止序列、seed复现、grammar结构化约束与stream流式输出,把/v1/completions改造成满足具体业务需求的补全服务。相关源码均可在此仓库中继续深挖:Python 示例、路由与解析实现、请求结构体定义、serve 命令入口。
【免费下载链接】mistral.rsFast, flexible LLM inference项目地址: https://gitcode.com/GitHub_Trending/mi/mistral.rs
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考