使用 Modal 在云端 GPU 上运行 Outlines 结构化生成:从镜像构建到 JSON Schema 约束推理完整指南

发布时间:2026/9/14 15:54:29
使用 Modal 在云端 GPU 上运行 Outlines 结构化生成:从镜像构建到 JSON Schema 约束推理完整指南 使用 Modal 在云端 GPU 上运行 Outlines 结构化生成从镜像构建到 JSON Schema 约束推理完整指南【免费下载链接】outlinesStructured Outputs项目地址: https://gitcode.com/GitHub_Trending/ou/outlines导读本文是一份端到端的实战指南讲解如何借助 Modal 示例文件可直接对照运行。为什么用 Modal 跑 OutlinesOutlines 是一个结构化输出Structured Outputs生成框架其核心思想是在生成过程中保证输出结构合法而不是生成完再靠解析去修补。但要让这一能力落地前提是你有一块能跑大模型的 GPU。Modal 是一个 Serverless 云平台可以按需为你在云端创建 GPU 实例并在几秒钟内完成代码打包、容器构建与调度。把两者结合就能在没有本地怪兽级显卡的情况下快速、弹性地在云端完成带格式约束的模型推理。环境准备官方建议在虚拟环境中安装modal与outlines。先创建并激活虚拟环境python -m venv venv source venv/bin/activate然后安装依赖包pip install modal outlines其中modal是 Modal 的 Python 客户端用于定义镜像、App、函数并触发云端执行outlines是本项目的结构化生成框架。如果你希望把仓库克隆到本地对照阅读也可以先git clone本项目后再进入examples/目录查看配套示例。构建容器镜像Modal 通过Image对象声明运行环境。下面的代码创建了一个基于 Debian slim 的 Python 3.11 镜像并预装 Outlines 及其依赖的 Transformers 生态组件from modal import Image, App, gpu import os # 创建 Modal App 对象名称为 outlines-app。 # 还有其它可选参数如 secrets、调度策略等。 app App(nameoutlines-app) # 指定要使用的语言模型。 # 另一个不错的选择是 NousResearch/Hermes-2-Pro-Mistral-7B language_model mistral-community/Mistral-7B-v0.2 # 请设置环境变量 HF_TOKEN值为你的 Hugging Face API token。 # 下面代码中的 .env({...}) 部分会把本地环境中的 token 拷贝进容器。 outlines_image Image.debian_slim(python_version3.11).pip_install( outlines, transformers, datasets, accelerate, sentencepiece, ).env({ # 这会把本地已有的 HF_TOKEN 环境变量带入容器。 HF_TOKEN: os.environ[HF_TOKEN] # 若想直接在代码中写死 token取消下面一行注释并替换成你的 token。 # HF_TOKEN:YOUR_TOKEN })要点说明Image.debian_slim(python_version3.11)声明基础镜像与 Python 版本pip_install(...)中的transformers、datasets、accelerate、sentencepiece是 Outlines 通过from_transformers加载 Hugging Face 模型时所依赖的关键库。若目标模型是 Hugging Face 上的门控模型gated model必须在容器内提供访问 token。最佳实践是通过.env({HF_TOKEN: os.environ[HF_TOKEN]})从本地环境透传避免把 token 明文写进代码代码中也保留了直接写死 token的注释行作为备选方案。仓库配套示例 examples/modal_example.py 对依赖版本做了显式锁定如outlines1.0.0、transformers4.38.2、datasets2.18.0、accelerate0.27.2在生产环境建议同样固定版本以获得可复现的构建。配置容器启动时预热模型对于需要长时间运行的 Modal 应用官方建议在容器启动时下载模型而不是等到函数被调用时才下载。这样模型权重会被缓存后续冷启动与重复运行都会显著加速# 该函数负责从 Hugging Face 拉取模型。 # Modal 容器启动时会调用它适合做模型下载、环境变量初始化等准备工作。 def import_model(): import outlines import transformers outlines.from_transformers( transformers.AutoModelForCausalLM.from_pretrained(language_model), transformers.AutoTokenizer.from_pretrained(language_model) ) # 这行代码告诉容器在启动时执行 import_model 函数。 outlines_image outlines_image.run_function(import_model)run_function是 Modal 镜像构建阶段的能力它会在构建镜像时于容器内执行一次import_model把模型权重固化进镜像层从而避免每次冷启动都重新下载数 GB 的参数文件。这也是后面推理函数内只需加载权重到显存而非下载权重的前提。定义输出 Schema约束 JSON 结构我们将复现 README 中的 JSON 结构化生成示例为角色描述定义一个 JSON Schema。Schema 中包含一个带name、age、armor、weapon、strength字段的角色对象其中armor与weapon通过$ref引用枚举定义schema { title: Character, type: object, properties: { name: { title: Name, maxLength: 10, type: string }, age: { title: Age, type: integer }, armor: {$ref: #/definitions/Armor}, weapon: {$ref: #/definitions/Weapon}, strength: { title: Strength, type: integer } }, required: [name, age, armor, weapon, strength], definitions: { Armor: { title: Armor, description: An enumeration., enum: [leather, chainmail, plate], type: string }, Weapon: { title: Weapon, description: An enumeration., enum: [sword, axe, mace, spear, bow, crossbow], type: string } } }这个 schema 中的enum是约束的核心模型只能在[leather, chainmail, plate]中选择装甲只能在六种武器中二选一或择一age与strength必须输出整数name不得超过 10 个字符。在推理时Outlines 会把该 schema 编译为 logits 处理器logits processor在每一步解码时屏蔽掉不可能满足 schema 的 token从而从机制上保证输出合法。从源码看Outlines 的JsonSchema类型位于 src/outlines/types/dsl.py它的构造参数非常灵活除了本文使用的 JSON schema字符串还接受dict、Pydantic 模型、TypedDict、dataclass 以及 genSON schema builder。构造时会通过jsonschema.Draft7Validator.check_schema对 schema 做合法性校验并支持whitespace_pattern与ensure_ascii等选项。在outlines.types包中JsonSchema与CFG、Regex、Choice等 DSL 类型一起构成结构化输出的类型体系见 src/outlines/types/init.py并在顶层通过outlines.json_schema导出见 src/outlines/init.py。编写云端推理函数在 Modal 上做推理需要把推理逻辑包进app.function装饰器中并把镜像与 GPU 规格作为参数传入。下面选择 A100 80GB 实例app.function(imageoutlines_image, gpugpu.A100(size80GB)) def generate( prompt: str Amiri, a 53 year old warrior woman with a sword and leather armor., ): # 注意此函数运行在容器内因此需要在这里导入所需库。 import outlines import transformers from outlines.types import JsonSchema # 将模型加载进显存。前面的 import_model 已完成下载 # 所以这里只负责把权重加载到 GPU 内存。 outlines.from_transformers( transformers.AutoModelForCausalLM.from_pretrained(language_model, device_mapcuda), transformers.AutoTokenizer.from_pretrained(language_model) ) # 基于模型与 JSON schema 创建生成器。 generator outlines.Generator(model, JsonSchema(schema)) # 用指令标签 ([INST] 与 [/INST]) 包裹 prompt指示这是指令任务。 # 不同模型的指令标签格式不同请以模型官方文档为准。 character generator( fs[INST]Give me a character description. Describe {prompt}.[/INST] ) # 打印生成的角色描述。 print(character)几个值得展开的实现细节为什么要在函数内重新导入库app.function中的函数体运行在远端容器进程里与本地 Python 进程不共享命名空间因此outlines、transformers需要在函数内显式导入。device_mapcuda把模型权重显式放到 GPU 上。仓库中from_transformers的实现位于 src/outlines/models/transformers.py它根据传入的是PreTrainedTokenizer还是ProcessorMixin分别构造Transformers或TransformersMultiModal包装器。该包装器的generate方法会把用户传入的输出类型转成transformers的LogitsProcessorList后交给model.generate执行见同文件 L269-L313。outlines.Generator(model, JsonSchema(schema))做了什么见 src/outlines/generator.pySteerableGenerator在构造时会把JsonSchema类型通过python_types_to_terms归一化再调用get_json_schema_logits_processor预编译出 logits 处理器并缓存。logits 处理器的构建通常比较昂贵因此 Generator 把它存储复用在每次调用时reset()后传入模型见 L280-L300。这正是结构化生成的底层原理推理过程中每一步采样都被 logits 处理器约束只允许产出符合 JSON Schema 的 token 序列。指令标签instruction tagsMistral 系模型要求用s[INST] ... [/INST]包裹指令不同厂商/家族的模型标签格式可能不同务必查阅所选模型文档。定义本地入口并触发云端执行app.local_entrypoint()装饰器把main声明为使用 Modal CLI 启动时的本地入口函数app.local_entrypoint() def main( prompt: str Amiri, a 53 year old warrior woman with a sword and leather armor., ): # 调用上面定义的 generate 函数。.remote() 表示在云端机器上运行 # 若想本地运行可改用 .local()但需要额外的环境配置。 generate.remote(prompt)generate.remote(prompt)会触发一次远程函数调用Modal 先在云端拉起或复用配置了outlines_image的容器将请求调度到 A100 GPU 上执行generate再把函数内的print输出回传终端。仓库中的 examples/modal_example.py 是同一方案的完整可运行版本可作为对照它固定了依赖版本、使用mistralai/Mistral-7B-Instruct-v0.2模型、用gpuA100-40GB声明 GPU字符串形式的简写并采用outlines.json_schema(schema)的简洁 API 直接在模型调用中指定 schema。你可以把本指南中的代码保存为example.py或直接参考该文件。在云端运行首先确认已安装 Modal 客户端如未安装则执行pip install modal然后获取 Modal 访问 token 并完成本地配置modal setup按提示完成认证后一条命令即可在云端运行推理modal run example.py运行过程中你会看到 Modal 应用初始化构建镜像、拉起容器、加载模型随后终端中很快出现print函数输出的角色描述例如一个包含name、age、armor、weapon、strength五个字段、且完全符合上文 JSON Schema 的合法 JSON。至此一次云端 GPU 结构化生成的完整链路就跑通了。常见问题与调优建议门控模型 403确保本地已设置HF_TOKEN环境变量且 token 具备目标模型仓库的访问权限镜像构建时.env(...)只在有该环境变量时才能成功透传。冷启动过慢确认import_model已通过run_function挂到镜像上让模型下载发生在镜像构建阶段而非运行时首次运行后 Modal 会缓存镜像与模型后续启动显著加快。GPU 选型7B 级模型用 A100-40GB 即可见 examples/modal_example.py更大模型再考虑 A100-80GB 或更高规格Modal 支持多种 GPU 简写可参考其官方 GPU 文档。调试与验证本仓库的 tests/models/test_transformers.py 展示了from_transformers的实例化契约如错误传入int会抛ValueError、Mamba/BART 等架构均被支持、device_dtype参数可指定torch.bfloat16等本地调试结构化生成时可参考这些测试来验证模型包装是否正确。小结本文完整演示了Modal 云端 GPU Outlines 结构化生成的落地路径先通过Image.debian_slim().pip_install().env().run_function()构建并预热镜像再用app.function(image..., gpu...)声明带 GPU 的推理函数配合outlines.Generator(model, JsonSchema(schema))完成受 JSON Schema 约束的生成最后由app.local_entrypoint()加modal run一键触发。整个过程无需本地 GPU也无需手动运维云主机——这正是 Serverless 平台与结构化生成框架结合的价值所在。【免费下载链接】outlinesStructured Outputs项目地址: https://gitcode.com/GitHub_Trending/ou/outlines创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询