https://github.com/mizorewww/laya-mlx https://github.com/mizorewww/laya-coreml
要运行 aac6fef/laya-coreml 并提供 Type-Safe(类型安全) 兼容的 API,最有效的方法是结合 Python 的 laya_coreml 库,并利用 Pydantic 或 Python 3.10+ 的 TypedDict / Literal 对输入结构与返回概率进行严格的类型约束。
由于该模型不是生成文本的大模型,而是直接返回“选择题、评分或布尔判断”的概率,我们可以完美地用类型系统将模型输入输出锁死,从而在编译器或 IDE(如 VS Code / PyCharm)中获得完整的类型提示。 [1]
下面是为您编写的完整运行及 Type-Safe API 封装方案:
1. 环境准备 确保你的运行环境是 Apple Silicon Mac (M1/M2/M3/M4 系列),且系统为 macOS 15及以上。 [2]
1 2 pip install laya-coreml pydantic
2. 构建 Type-Safe 兼容的 API 封装 我们可以定义严格的 DecisionSchema 类型。因为模型原生支持 noul(布尔判断)、选择或评分,我们使用 Pydantic 建立前端/上层业务与底层模型的桥梁:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 from typing import Dict , Literal , Union , List from pydantic import BaseModel, Fieldimport laya_coreml as layaclass BooleanQuestion (BaseModel ): type : Literal ["noul" ] = "noul" instructions: str = Field(..., description="需要模型判断的布尔条件,例如:'用户是否在申请退款?'" ) class ChoiceQuestion (BaseModel ): type : Literal ["choice" ] = "choice" options: List [str ] = Field(..., description="供选择的标签列表" ) instructions: str = Field(..., description="分类指令" ) QuestionConfig = Dict [str , Union [BooleanQuestion, ChoiceQuestion]] class InferenceRequest (BaseModel ): text: str = Field(..., description="需要分析的上下文或用户原始文本" ) questions: QuestionConfig = Field(..., description="强类型定义的问题字典" ) class InferenceResponse (BaseModel ): answers: Dict [str , Union [float , Dict [str , float ]]] = Field( ..., description="模型决策的原始概率分布(无自回归解码)" ) class LayaCoreMLClient : def __init__ (self, model_id: str = "aac6fef/laya-coreml" ): """ 初始化并加载 Core ML 模型,首次运行会自动下载并缓存在本地 ANE (Neural Engine) 中 """ print (f"Loading CoreML model '{model_id} ' onto Neural Engine..." ) self .agent = laya.load(model_id) def predict (self, request: InferenceRequest ) -> InferenceResponse: """ 执行类型安全的本地推理 """ raw_questions = {k: v.model_dump() for k, v in request.questions.items()} raw_result = self .agent.predict(request.text, raw_questions) return InferenceResponse(answers=raw_result["answers" ])
3. 如何运行与调用示例 将上述封装实例化后,直接通过对象传递。IDE 会全程动态校验你的参数类型是否合法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 if __name__ == "__main__" : client = LayaCoreMLClient("aac6fef/laya-coreml" ) payload = InferenceRequest( text="尊敬的客服,我昨天不小心多付了一笔重复的账单,请帮我处理退款。" , questions={ "is_refund_request" : BooleanQuestion( instructions="Does the customer request a refund for a duplicate payment?" ), "intent_category" : ChoiceQuestion( instructions="Classify the intent of the user request." , options=["billing_issue" , "technical_support" , "account_close" ] ) } ) response = client.predict(payload) print ("--- 决策推理结果 ---" ) print (f"退款意图概率: {response.answers.get('is_refund_request' )} " ) print (f"分类概率分布: {response.answers.get('intent_category' )} " )
💡 生产环境避坑指南
Token 限制: 默认的 aac6fef/laya-coreml 为了追求极致的 ANE 加速,总 Token 预算限制在 96 以内(包括 text + instructions)。如果你的输入过长,模型会抛出容量错误。 [1]
长文本平替: 如果输入文本可能超过 96 tokens,请在初始化时将模型 ID 替换为通用版本 aac6fef/laya-multilingual-coreml,该版本支持 1024-token 的长文本输入。 [1]
你需要我帮你把这套 Type-Safe API 进一步包装成 FastAPI 接口服务 供外部调用,还是想了解如何为它编写 自动化单元测试(Pytest) 以验证输入边界?
[1] https://github.com
[2] https://github.com
要将 aac6fef/laya-coreml 封装为类型安全(Type-Safe)的 HTTP API,最标准的做法是使用 FastAPI。 FastApi 原生与 Pydantic 完美绑定,它能自动根据你定义的 Python 输入/输出类型,在对外暴露的 HTTP 接口上生成一份完全符合 OpenAPI 规范的端点文档(即可以通过浏览器直接访问的 /docs 页面)。 [1]
以下是完整的开发及运行步骤:
1. 安装 HTTP 服务器依赖 首先确保你已经安装了 laya-coreml、fastapi 和用于运行 HTTP 服务的 uvicorn: [2]
1 pip install laya-coreml fastapi uvicorn pydantic
2. 编写高性能 HTTP 服务代码 (app.py) 模型非自回归解码的特性决定了它的推理延迟极低(~5ms),利用 FastAPI 的异步入口配合统一的模型客户端,能够提供极其稳定的吞吐量。 [3]
我们将输入字段字段标准化为符合社区生态的 state 与 questions 映射格式: [1]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 from contextlib import asynccontextmanagerfrom typing import Dict , Literal , Union , List from fastapi import FastAPI, HTTPExceptionfrom pydantic import BaseModel, Fieldimport laya_coreml as layaclass BooleanQuestion (BaseModel ): type : Literal ["noul" ] = "noul" instructions: str = Field(..., description="需要判断的布尔决策指令" ) class ChoiceQuestion (BaseModel ): type : Literal ["choice" ] = "choice" options: List [str ] = Field(..., description="供选择的分类标签列表列表" ) instructions: str = Field(..., description="多分类指令" ) QuestionConfig = Dict [str , Union [BooleanQuestion, ChoiceQuestion]] class ModelRequest (BaseModel ): state: str = Field(..., description="需要分析的上下文文本或 JSON 字符串" ) questions: QuestionConfig = Field(..., description="由强类型定义的问题映射表" ) class ModelResponse (BaseModel ): answers: Dict [str , Union [float , Dict [str , float ]]] = Field( ..., description="模型决策的原始概率分布(无自回归,输出极其确定)" ) model_agent = None @asynccontextmanager async def lifespan (app: FastAPI ): global model_agent print ("正在加载 Core ML 模型至 Apple Neural Engine (ANE)..." ) model_agent = laya.load("aac6fef/laya-coreml" ) print ("模型加载完成,服务已就绪!" ) yield model_agent = None app = FastAPI( title="Laya CoreML Type-Safe API" , version="1.0.0" , lifespan=lifespan ) @app.post("/ai/run" , response_model=ModelResponse ) async def run_inference (payload: ModelRequest ): """ 接收强类型的 HTTP 决策请求,在本地 ANE 硬件上以超低延迟执行推理。 """ if model_agent is None : raise HTTPException(status_code=503 , detail="Model not initialized yet." ) try : raw_questions = {k: v.model_dump() for k, v in payload.questions.items()} raw_result = model_agent.predict(payload.state, raw_questions) return ModelResponse(answers=raw_result["answers" ]) except Exception as e: raise HTTPException(status_code=400 , detail=f"Inference error: {str (e)} " )
3. 运行本地 HTTP 服务器 在终端中执行以下命令启动服务:
1 uvicorn app:app --host 127.0.0.1 --port 8000 --reload
4. 客户端调用与 Type-Safe 验证 1) 自动生成的交互式接口文档 (OpenAPI) 启动后,直接在浏览器中打开 http://127.0.0,你会看到一个清晰的 Swagger 页面。前端团队可以基于此页面直接下载 openapi.json,并利用工具(如 openapi-typescript)直接为 TypeScript 生成完全类型安全的网络请求代码。 [4, 5]
2) cURL 验证测试 此时,其他系统可以通过完全结构化的 JSON 对你的 Mac 节点进行请求:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 curl http://127.0.0 \ -H "Content-Type: application/json" \ -d '{ "state": "不好意思,我刚才买错了规格,我想退货换成大号的,麻烦退一下款。", "questions": { "is_urgent": { "type": "noul", "instructions": "用户是否在申请退款或退换货?" }, "category": { "type": "choice", "instructions": "分类用户的主要意图", "options": ["after_sales", "consulting", "complaint"] } } }'
响应结果(完美符合绑定的类型输出格式):
1 2 3 4 5 6 7 8 9 10 { "answers" : { "is_urgent" : 0.9854 , "category" : { "after_sales" : 0.9621 , "consulting" : 0.0315 , "complaint" : 0.0064 } } }
目前这个服务运行在本地。如果你需要把它部署到局域网其他机器访问,或者需要对输入进行 Token 长度预切片(避免超出 96 token 预算报错),请告诉我!
[1] https://gist.github.com
[2] https://gist.github.com
[3] https://hype.replicate.dev
[4] https://itnext.io
[5] https://dev.to