尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Outlines SGLang 集成实战:通过 OpenAI 兼容接口在 SGLang 服务器上实现结构化生成

发布时间:2026/9/14 7:25:16

资讯中心
01
ARTICLE

Outlines SGLang 集成实战:通过 OpenAI 兼容接口在 SGLang 服务器上实现结构化生成

Outlines SGLang 集成实战:通过 OpenAI 兼容接口在 SGLang 服务器上实现结构化生成
Outlines SGLang 集成实战通过 OpenAI 兼容接口在 SGLang 服务器上实现结构化生成【免费下载链接】outlinesStructured Outputs项目地址: https://gitcode.com/GitHub_Trending/ou/outlines导读本文围绕 Outlines 提供的 SGLang 后端集成官方文档完整讲解如何将独立部署的 SGLang 推理服务器接入 Outlines使用outlines.from_sglang完成文本生成、视觉输入、流式输出以及基于 Python 类型、JSON Schema、正则和 EBNF 文法约束的结构化生成。读完本文你将掌握从零启动 SGLang 服务器、初始化同步/异步模型、定制推理参数以及深入理解 Outlines 将输出类型转换为 SGLang 约束请求的底层机制。前置条件先让 SGLang 服务器跑起来Outlines 的SGLang模型是一个客户端包装器它本身不加载模型权重而是面向一个独立运行的 SGLang 服务器本地或远程均可发起请求。因此使用前必须保证 SGLang 服务器已启动且可访问。最小化启动方式如下pip install sglang[all] python -m sglang.launch_server \ --model-path NousResearch/Meta-Llama-3-8B-Instruct \ --host 0.0.0.0 \ --port 30000要点说明--model-path可以是 Hugging Face 上的任意模型仓库也可以换成你实际要用的模型--host 0.0.0.0表示监听所有网卡便于局域网内的客户端访问--port 30000是服务端口后续所有 Outlines 客户端的base_url都要指向它文档示例代码中使用的http://localhost:11434仅为示意地址实际请填写你 SGLang 服务器的地址例如http://localhost:30000服务器具体安装方式因硬件与 CUDA 环境而异请参考 SGLang 官方安装说明。指定结构化生成后端引擎启动 SGLang 服务器时可以通过--grammar-backend参数指定用于结构化生成的后端引擎python -m sglang.launch_server \ --model-path NousResearch/Meta-Llama-3-8B-Instruct \ --host 0.0.0.0 \ --port 30000 \ --grammar-backend outlines添加--grammar-backend outlines即可让 SGLang 使用 Outlines 作为约束解码引擎而不是默认引擎。客户端依赖由于 Outlines 的 SGLang 客户端依赖openaiPython SDK服务器暴露的是 OpenAI 兼容接口需要先安装 Outlines 的sglang可选依赖pip install outlines[sglang]从 pyproject.toml 可以看到该可选依赖组实际就是[openai]。注意这是Outlines 侧的依赖SGLang 服务器本身不受影响。模型初始化from_sglang导入模型使用outlines.from_sglang函数。它的唯一参数是openai库的OpenAI或AsyncOpenAI客户端实例并要求客户端的base_url指向你正在运行的 SGLang 服务器。import openai import outlines # 创建 OpenAI 客户端 sync_openai_client openai.OpenAI(base_urlhttp://localhost:30000) async_openai_client openai.AsyncOpenAI(base_urlhttp://localhost:30000) # 创建同步模型 sync_model outlines.from_sglang(sync_openai_client) print(type(sync_model)) # class outlines.models.sglang.SGLang # 创建异步模型 async_model outlines.from_sglang(async_openai_client) print(type(async_model)) # class outlines.models.sglang.AsyncSGLang根据传入客户端是同步还是异步你会分别得到SGLang或AsyncSGLang实例。从源码看from_sglang 通过isinstance判断客户端类型传入openai.OpenAI→ 返回SGLang传入openai.AsyncOpenAI→ 返回AsyncSGLang其他类型直接抛出ValueError(Unsupported client type ...)。此外from_sglang还接受可选的model_name参数。若不传则请求不会携带model字段由服务器端默认模型处理若传入_build_client_args会在用户未显式指定model时自动补上该参数若用户在调用时显式传了model则以调用时的为准。两个模型类本质上都是openai客户端的薄包装见 SGLang 类 与 AsyncSGLang 类 的 docstring负责把用户层面的输入、输出类型翻译成客户端参数。文本生成初始化模型后直接以字符串 prompt 调用即可生成文本import openai import outlines # 创建模型 model outlines.from_sglang(openai.OpenAI(base_urlhttp://localhost:30000)) # 调用生成文本 response model(Whats the capital of Latvia?, max_tokens20) print(response) # Riga多采样n 参数调用时传入 OpenAI 兼容的n参数可以一次返回多个候选结果。从 generate 实现看当响应中只有一个choice时返回str多个choice时返回str列表response model(Respond with a single word., n2) print(response) # [foo, bar]视觉输入Vision部分可通过 SGLang 运行的模型支持视觉输入。此时以「文本 Image实例」组成的列表作为 prompt 即可import io import requests import PIL import outlines import openai from outlines.inputs import Image # 创建模型 model outlines.from_sglang(openai.OpenAI(base_urlhttp://localhost:30000)) # 获取图片的函数 def get_image(url): r requests.get(url) return PIL.Image.open(io.BytesIO(r.content)) # 构造包含文本和图片的 prompt prompt [ Describe the image, Image(get_image(https://picsum.photos/id/237/400/300)) ] # 调用模型生成回复 response model(prompt, max_tokens50) print(response) # This is a picture of a black dog.Image数据类定义在 inputs.py它会读取 PIL 图片的格式将其 base64 编码保存到image_str并在请求时以data:image/png;base64,...的 data URL 形式传给服务器这是OpenAITypeAdapter的统一格式约定SGLang 适配器直接复用见 test_sglang_type_adapter.py 中的输入断言。聊天输入ChatSGLang模型同样支持聊天输入将Chat实例传给模型即可。聊天内容可以是纯文本也可以像上面一样混入图片import io import requests import PIL import openai import outlines from outlines.inputs import Chat, Image # 创建模型 model outlines.from_sglang(openai.OpenAI(base_urlhttp://localhost:30000)) # 获取图片的函数 def get_image(url): r requests.get(url) return PIL.Image.open(io.BytesIO(r.content)) # 构造聊天输入 prompt Chat([ {role: system, content: You are a helpful assistant.}, { role: user, content: [Describe the image, Image(get_image(https://picsum.photos/id/237/400/300))] }, ]) # 调用模型生成回复 response model(prompt, max_tokens50) print(response) # This is a picture of a black dog.Chat 数据类要求每条消息是含role与content键的字典role支持system/user/assistant同时提供add_user_message、add_assistant_message、add_system_message、append、extend、pop等便捷方法。流式输出StreamingSGLang模型通过stream方法支持流式输出逐块返回生成的文本import openai import outlines # 创建模型 model outlines.from_sglang(openai.OpenAI(base_urlhttp://localhost:30000)) # 流式获取响应 for chunk in model.stream(Tell me a short story about a cat., max_tokens50): print(chunk) # Once...底层实现见 generate_stream它调用chat.completions.create(..., streamTrue)并逐个产出chunk.choices[0].delta.content非空片段异步版本的 AsyncSGLang.generate_stream 行为一致只是返回异步迭代器。不支持批处理需要注意SGLang 模型不支持batch批处理接口。同步与异步模型的generate_batch都直接抛出NotImplementedError(SGLang does not support batch inference.)见 sglang.py 与 AsyncSGLang对应测试见 test_sglang.py。结构化生成SGLang 支持全部输出类型SGLang 后端支持 Outlines 提供的所有输出类型上下文无关文法有例外见下文小节。调用时在 prompt 后直接传入output_type即可。所有结构化生成特性在同步与异步模型上均可使用。简单类型Python 内置类型import openai import outlines output_type int openai_client openai.OpenAI(base_urlhttp://localhost:30000) model outlines.from_sglang(openai_client) result model(How many countries are there in the world?, output_type) print(result) # 200从源码看int这类 Python 类型会经过python_types_to_terms转换后走正则路径。测试断言format_output_type(int)会生成{extra_body: {regex: ([-]?(0|[1-9][0-9]*))}}见 test_sglang_type_adapter.py即整数的输出被约束为可选正负号加十进制整数的正则。JSON SchemaPydantic 模型import openai import outlines from typing import List from pydantic import BaseModel class Character(BaseModel): name: str age: int skills: List[str] openai_client openai.OpenAI(base_urlhttp://localhost:30000) model outlines.from_sglang(openai_client) result model(Create a character., Character, frequency_penalty1.5) print(result) # {name: Evelyn, age: 34, skills: [archery, stealth, alchemy]} print(Character.model_validate_json(result)) # nameEvelyn, age34, skills[archery, stealth, alchemy]Pydantic 模型最终会转换为 JSON Schema并通过response_format参数typejson_schema、strictTrue传给服务器。底层由SGLangTypeAdapter.format_output_type的JsonSchema分支处理sglang.py它复用OpenAITypeAdapter.format_json_output_type见 openai.py并强制把 Schema 中所有对象的additionalProperties设为False。测试对JsonSchema的完整输出断言见 test_sglang_type_adapter.py。多选一Literalfrom typing import Literal import openai import outlines output_type Literal[Paris, London, Rome, Berlin] openai_client openai.OpenAI(base_urlhttp://localhost:30000) model outlines.from_sglang(openai_client) result model(What is the capital of France?, output_type, temperature0) print(result) # ParisLiteral与简单类型一样走正则路径to_regex生成形如(Paris|London|Rome|Berlin)的约束确保模型只输出候选之一。正则表达式Regeximport openai import outlines from outlines.types import Regex output_type Regex(r\d{3}-\d{2}-\d{4}) openai_client openai.OpenAI(base_urlhttp://localhost:30000) model outlines.from_sglang(openai_client) result model(Generate a fake social security number., output_type, top_p0.1) print(result) # 782-32-3789正则约束最终以extra_body: {regex: ...}的形式传给 SGLang 服务器。此外 outlines.types 还预置了大量开箱即用的正则类型例如integer、boolean、email、uuid4、ipv4、ipv6、credit_card、semver等均可直接作为output_type使用。上下文无关文法CFG / EBNF这是 SGLang 后端的特例SGLang 支持文法约束但期望的是EBNF格式而不是 Outlines 通用的 Lark 格式。因此要对 SGLang 使用文法需要把 EBNF 语法字符串传给 Outlines 的CFG对象import openai import outlines from outlines.types import CFG ebnf_grammar root :: answer answer :: yes | no output_type CFG(ebnf_grammar) openai_client openai.OpenAI(base_urlhttp://localhost:30000) model outlines.from_sglang(openai_client) result model(Is the weather good today?, output_type) print(result) # yes从源码看sglang.py当output_type是CFG时Outlines 会发出UserWarningSGLang 的文法结构化输出期望 EBNF 文法而不是 Outlines 通常使用的 Lark 文法该文法不能配合 Outlines 后端使用只兼容 SGLang 与 llguidance 后端。随后约束以extra_body: {ebnf: 文法定义}传给服务器。对应测试见 test_sglang.pyEBNF 语法root :: answer / answer :: yes | no生成结果必须是yes或no。实际联调提示当使用真实 SGLang 服务器运行这类测试时test_sglang.py 文件头注释建议使用--grammar-backend llguidance因为 Outlines 后端不支持 EBNF 文法而 xgrammar 后端较慢且易出问题。异步结构化生成所有结构化生成特性对异步模型同样可用import asyncio import openai import outlines from typing import List from pydantic import BaseModel class User(BaseModel): name: str email: str age: int async def generate_user(): async_client openai.AsyncOpenAI(base_urlhttp://localhost:30000) async_model outlines.from_sglang(async_client) result await async_model(Generate a random user profile., output_typeUser) user User.model_validate_json(result) print(fName: {user.name}, Email: {user.email}, Age: {user.age}) asyncio.run(generate_user())AsyncSGLang.generate使用await self.client.chat.completions.create(**client_args)完成请求其余逻辑拒绝检查、多返回处理与同步版本完全一致。推理参数与 extra_body调用模型时可以在 prompt 和输出类型之外传入任意可选参数它们会被原样透传给openai客户端的chat.completions.create方法例如上面示例中的max_tokens、temperature、top_p、frequency_penalty、n等。特别值得关注的是extra_body参数它是一个字典用来携带SGLang 特有、不属于标准openai接口的附加参数。从_build_client_args的实现sglang.py可以看到一个关键细节当结构化输出需要放入extra_body如regex、ebnf时Outlines 会先复制用户传入的extra_body再把结构化输出键合并进去而不是整体覆盖extra_body dict(inference_kwargs.pop(extra_body, {}) or {}) extra_body.update(output_type_args.pop(extra_body)) inference_kwargs[extra_body] extra_body这意味着你可以同时使用自定义的 SGLang 参数与结构化约束。例如result model( Generate a fake social security number., Regex(r\d{3}-\d{2}-\d{4}), extra_body{some_sglang_specific_option: True}, )测试 test_sglang_build_client_args_merges_user_extra_body 验证了用户自定义键user_key与结构化键regex能共存于最终的extra_body中test_sglang_build_client_args_does_not_mutate_caller_extra_body 则验证了复制策略的意义——调用方传入的extra_body字典不会被原地修改且非结构化调用不会残留上一次的regex/ebnf键对应 issue #1931 的修复。底层原理小结SGLangTypeAdapter.format_output_typesglang.py是结构化生成的转换核心——None返回空参数字典CFG产生extra_body.ebnfJsonSchema复用 OpenAI 的response_format.json_schema其余一切Python 类型、Literal、Regex 等统一收敛为extra_body.regex。也就是说SGLang 后端把「JSON 约束」与「正则/EBNF 约束」分成了response_format与extra_body两条通道。错误处理与边界行为异常归一化SGLang 模型的所有客户端调用都被 normalize_provider_errors(sglang) 包裹。由于 SGLang 复用 OpenAI SDKexceptions.py 的异常映射表将openai的各类 SDK 异常AuthenticationError、RateLimitError、APITimeoutError等映射为 Outlines 统一的APIError子类层次便于上层统一捕获。拒绝响应若服务器的message.refusal非空模型会抛出GenerationError提示服务器拒绝回答sglang.py。无效客户端类型from_sglang收到非OpenAI/AsyncOpenAI实例时抛出ValueError对应测试 test_sglang_init。输入类型限制SGLangTypeAdapter.format_input复用OpenAITypeAdaptersglang.py只接受str、list与Chat三种输入其他类型如任意 dataclass 对象抛出TypeError见 test_sglang_type_adapter.py。批处理batch不可用调用即抛NotImplementedError。与 OpenAI 兼容生态的关系SGLang 服务器对外提供 OpenAI 兼容的 Chat Completions 接口这正是 Outlines 可以复用openaiSDK 与OpenAITypeAdapter的原因。两者的差异点在于约束能力标准 OpenAI 接口不支持正则与文法约束而 SGLang 通过extra_bodyregex/ebnf补上了这条通道。因此SGLang与AsyncSGLang在 models/init.py 中被归入BlackBoxModel/AsyncBlackBoxModel与 OpenAI、Mistral、TGI、VLLM 等远程服务并列。想要进一步验证行为可以直接查看或运行 tests/models/test_sglang.py 与 tests/models/test_sglang_type_adapter.py测试通过环境变量SGLANG_SERVER_URL决定是连接真实服务器还是使用 mock 客户端覆盖了同步/异步、视觉、聊天、流式、多采样、JSON/Regex/CFG 等全部路径是理解该集成行为的权威参考。【免费下载链接】outlinesStructured Outputs项目地址: https://gitcode.com/GitHub_Trending/ou/outlines创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。