Skip to content

SGLang 编程模型与约束解码

SGLang 不仅是一个推理引擎,还提供了一套编程模型来精确控制大语言模型的生成过程。通过约束解码和结构化生成,可以确保模型输出严格符合预定义的格式。

SGLang编程模型

SGLang 编程原语

SGLang 提供以下核心编程原语:

  • gen:生成文本,支持采样参数控制
  • select:从候选选项中选择
  • fork:创建并行分支
  • image:多模态输入
python
import sglang as sgl

@sgl.function
def multi_choice_question(s, question, options):
    """结构化多选题生成"""
    s += question + "\n"
    s += "选项:\n"
    for i, opt in enumerate(options):
        s += f"{chr(65+i)}. {opt}\n"
    s += "正确答案是:" + sgl.gen("answer", max_tokens=1, regex="[A-D]")
    s += "\n解释:" + sgl.gen("explanation", max_tokens=200)

# 执行
runtime = sgl.Runtime(model_path="meta-llama/Llama-2-7b-hf")
result = multi_choice_question.run(
    runtime,
    question="以下哪个不是 Python 的内置数据类型?",
    options=["list", "dict", "array", "tuple"],
)
print(result["answer"])      # C
print(result["explanation"])  # array 是 numpy 的...

约束解码

约束解码通过正则表达式或 JSON Schema 限制生成空间:

python
# 正则约束
@sgl.function
def extract_info(s, text):
    s += "从以下文本中提取信息:\n" + text + "\n"
    s += "姓名:" + sgl.gen("name", regex="[\\u4e00-\\u9fa5]{2,4}") + "\n"
    s += "电话:" + sgl.gen("phone", regex="1[3-9]\\d{9}") + "\n"
    s += "邮箱:" + sgl.gen("email", regex="[\\w.]+@[\\w.]+\\.com")

# JSON Schema 约束
from pydantic import BaseModel

class PersonInfo(BaseModel):
    name: str
    age: int
    city: str

@sgl.function
def json_extract(s, text):
    s += "提取为JSON:" + text + "\n"
    s += sgl.gen("result", schema=PersonInfo.schema_json())

分支与并行

SGLang 支持 fork 原语实现并行推理:

python
@sgl.function
def debate(s, topic):
    """正反方辩论生成"""
    s += f"辩论主题:{topic}\n\n"

    # 创建两个并行分支
    forks = s.fork(2)
    forks[0] += "正方观点:" + sgl.gen("pro", max_tokens=200)
    forks[1] += "反方观点:" + sgl.gen("con", max_tokens=200)

    # 合并分支
    s += "正方:" + forks[0]["pro"] + "\n"
    s += "反方:" + forks[1]["con"] + "\n"
    s += "总结:" + sgl.gen("summary", max_tokens=300)

约束解码的性能

约束解码通过限制词表空间,不仅保证输出格式正确,还能加速生成过程。正则约束可将无效 Token 的概率直接置零,减少采样步数。

与其他方案对比

方案约束类型性能开销灵活性
SGLang正则/Schema
Guidance语法树
OutlinesFSM
JSON ModeJSON Schema

正则复杂度

过于复杂的正则表达式可能导致约束解码的 DFA 状态数爆炸,影响推理速度。建议将复杂约束拆分为多个简单步骤。

相关资源

最近更新