ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Laya 原始检查点到 Apple Core ML:laya-coreml 可复现导出与验证实战指南

Laya 原始检查点到 Apple Core ML:laya-coreml 可复现导出与验证实战指南 【免费下载链接】laya-coremlLocal Laya typed decisions on Apple Core ML and Neural Engine. Validated ports, ~5 ms short decisions on M3 Max, reproducible speed and energy benchmarks.项目地址https://gitcode.com/gh_mirrors/la/laya-coreml点击查看免费下载在 Apple Silicon 上本地运行开源 Laya 类型化决策模型核心挑战是把上游原始 PyTorch 检查点可靠地转换成 Core ML ML Program并保证转换结果与上游行为一致。本文以 docs/CONVERSION.md 为主干结合仓库源码完整讲解 laya-coreml 的转换管线从 FP32 PyTorch 模块加载、TorchScript 追踪、形状签名设计到失败模式记录、设备证据边界、Hub 快照加载修复与可复现清单机制。读完本文你将掌握laya-coreml convert的全部参数语义、形状枚举与运行时 padding 规则、如何复现已知失败的转换实验以及如何用 golden reference 独立验证转换保真度。转换管线总览无训练的推理专用导出docs/CONVERSION.md明确指出本页描述的是常规 Core ML 导出路径另行重写的 ANE 专用图与可选权重量化在 docs/ANE_ENGINEERING.md 中说明。导出过程严格遵循以下三步与 laya_coreml/convert.py 的convert()函数一一对应加载原始 Laya 检查点到 FP32 PyTorch 模块。这里的FP32描述的是导出/参考计算精度而非权重来源精度——发布的检查点文件本身以 FP16 张量为主。严格校验 state-dict 的所有键。load_model()使用model.load_state_dict(load_file(...), strictTrue)见 laya_coreml/torch_model.py任何键不匹配都会直接失败杜绝静默忽略某些权重导致的不一致。追踪一个仅推理实现的图torch.jit.trace(..., strictTrue, check_traceTrue)在torch.inference_mode()下执行并保存为Core ML ML Programconvert_tomlprogram。整个过程中不进行任何训练、剪枝或权重量化FP16 是转换精度选择FP32 可用于诊断。转换器明确拒绝了用 MLX 的 FP16 舍入导出权重的路径——源码注释写道Original checkpoints, never rounded MLX FP16 exports确保永远以原始检查点为准。运行时行为与上游完全对齐使用检查点的 tokenizer、prompt 布局、选项标记、问题类型嵌入、决策头、行动头与校准温度choice/score/noul、结构化标准、token 计数与零生成 token 均遵循上游 API。编码器是双向的每个问题都独立运行自己的编码器序列不存在跨问题的共享隐状态缓存——这一点在 laya_coreml/agent.py 的推理路径与 docs/USAGE.md 中都有呼应。已验证的转换选择docs/CONVERSION.md记录了经过验证的转换环境与形状决策全部可直接在仓库中找到对应证据依赖版本coremltools9.0、torch2.7.0、numpy2.1.3、Python 3.12。在 pyproject.toml 中运行依赖被钉在coremltools9,10、numpy1.26,2.2转换额外依赖torch2.7.0[project.optional-dependencies].convert与文档一致。TorchScript 追踪带图检查check_traceTrue、评估模式model.eval()、原始权重加载进 FP32 模块。部署目标ML Program 以minimum_deployment_targetct.target.macOS15导出对应 macOS 15 / iOS 18实际执行在 M3 MaxmacOS 27.2上测试过iPhone/iPad 与更老 macOS 未测试。清单中的minimum_deployment_target字段写为macOS15 / iOS18。默认序列长度从16, 32, 64, 96, 128, 192, 256, 384, 512, 768, 1024中选取不超过检查点上下文上限的值运行时把输入 padding 到最小的可用长度并掩码掉追加的 token。源码中lengths集合还额外并入max_length本身见 laya_coreml/convert.py。默认 batch 为 1带 32 个选项槽位marker slots更多问题分批处理。--batch-size与--max-options会生成不同的导出签名。固定形状适用于已知负载。输入超过导出的长度或选项容量时直接报错绝不静默截断去适配更小的导出原始检查点的上下文截断行为则被保留。Apple 官方文档涉及 TorchScript 转换与枚举输入形状多个枚举输入要求形状数量相同且按索引配对——本导出正是这样把input_ids与attention_mask一一配对的ct.EnumeratedShapes([(batch_size, n) for n in lengths], default...)同时作用于这两个输入见 laya_coreml/convert.py。转换器 CLI 与参数详解laya-coreml convert是唯一入口laya_coreml/cli.py其全部参数都直接转发给convert()参数默认值取值范围 / 语义源码校验位置source—本地检查点目录或受钉版本的 Laya 模型名自动加convaiinnovations/前缀的 Hub repo idlaya_coreml/convert.pyoutput—输出目录已存在则拒绝覆盖FileExistsErrorlaya_coreml/convert.py--max-length检查点max_len16..检查点上下文上限超出抛ValueErrorlaya_coreml/convert.py--batch-size11..64laya_coreml/convert.py--max-options322..255同上--fixed关开启后导出固定形状flexibleFalselaya_coreml/convert.py--precisionfloat16float16/float32laya_coreml/convert.py--revision受钉版本Hugging Face commit/revision映射表见REVISIONSlaya_coreml/convert.py--attentionsdpasdpascaled dot-product attention/explicitmatmulsoftmaxlaya_coreml/cli.py--shape-modeenumeratedenumerated/rangelaya_coreml/cli.py基础用法来自 docs/USAGE.md 与 docs/CONVERSION.mdpip install laya-coreml[convert] laya-coreml convert laya-multilingual models/custom-multilingualsource解析逻辑值得一提若路径不存在且不以.、~开头则当作 Hub repo id 处理通过snapshot_download只拉取model.safetensors、encoder/config.json、rl_agent_config.json与tokenizer/*见 laya_coreml/convert.py。受钉的发布 revision 分别为layac5d78730...、laya-multilingual052592a1...、laya-typed-decisionsf9ab0b22...。转换开始前会torch.set_num_threads(8)然后构造一组全零/全一的占位输入用于追踪追踪过程打印Tracing float16 B1, L..., K32, flexibleTrue之类的进度。转换成功后输出目录包含model.mlpackage、tokenizer/、encoder/config.json、rl_agent_config.json以及自动生成的coreml_config.json清单。导出签名与运行时形状处理五个 int32 输入、两个 float32 输出导出签名固定为 5 个输入、2 个输出laya_coreml/convert.py名称dtype形状语义input_idsint32(B, L)token id 序列attention_maskint32(B, L)有效 token 掩码padding 置 0marker_posint32(B, K)各选项[MASK]标记的位置索引marker_maskint32(B, K)选项是否有效qtypeint32(B,)问题类型choice0 / score1 / noul2见 laya_coreml/common.py 的QTYPESlogitsfloat32(B, K)各选项决策 logitsaction_logitsfloat32(B, A)行动头 logits运行时 padding向上取最小可用长度运行时输入组装由 laya_coreml/inputs.py 的collate_items()完成其规则与文档完全一致batch 必须为 1..导出 batch_size否则报错输入长度超过导出的max_length直接报错不静默截断选项数超过导出的max_options报错并提示用更大的值重新转换若清单中存在枚举lengthsenumerated 模式取 实际长度的最小枚举长度若flexible为 Truerange 模式向上取 16 的倍数并夹在[min_length, max_length]固定形状则直接用max_length追加的 padding token 被attention_mask置 0 掩码掉对于部分占用的固定 batchdummy 行保留attention_mask[:, 0] 1以保证每个假行都有一个有效键。对应的单元测试在 tests/test_model.pytest_traced_graph_handles_new_lengths_types_and_markers验证追踪图对新长度、类型与标记的兼容性test_padding_values_cannot_affect_valid_outputs则专门验证把 padding 区填成任意值如 99不会影响有效输出——这正是掩码掉追加 token的行为保证。macOS 专属测试test_real_coreml_conversion_and_dynamic_padding走完真实转换→加载→预测全链路并把 Core ML 输出与 PyTorch 参考输出做atol/rtol0.015的对齐断言同时校验usage[output_tokens] 0决策模型不生成 token。转换失败记录为可复现性保留的观察docs/CONVERSION.md明确声明以下观察仅针对当前机器与操作系统不代表所有 Core ML 版本。这些是值得工程团队记住的踩坑清单PyTorch 的__or__布尔运算符无法被转换。显式的torch.logical_or/torch.logical_and能保留相同的掩码语义。这正是源码中局部注意力掩码使用torch.logical_and(torch.logical_or(window[None, None], torch.logical_not(valid[:, None, :, None])), full)构建的原因laya_coreml/torch_model.py。NumPy 2.5 拒绝了 coremltools 9.0 内部一个已废弃的数组到标量转换。项目依赖被钉在 NumPy 2.2 以下PyTorch 被钉在转换器测试过的 2.7.0 而不是 2.7.1。这正是pyproject.toml中numpy1.26,2.2与torch2.7.0的直接原因。RangeDim配强制CPU_AND_GPU产生大数值误差且对重复相同输入给出不同结果。原 SDPA 导出只匹配 47/63 个参考答案显式 matmul/softmax 注意力只匹配 20/63FP32 也解决不了短输入 GPU 失败。CPU/自动选择下 SDPA 图输出正确。仓库中 benchmarks/results/ 下的validation-multilingual-sdpa-all.json、validation-multilingual-range-v2.json等文件即这些实验的原始留存。枚举长度恢复了 GPU 保真度与可重复性但随后一个独立的小回归测试暴露了 MPSGraph 编译器对切片常量布尔局部注意力矩阵的SIGTRAP诊断指向ElementsAttr::getValuesbool/FoldStridedSliceOp。最终实现改为先切片整数位置、之后再构造布尔局部掩码绕开了编译器陷阱。源码中的positionsbuffertorch.arange(max_length, dtypetorch.int32)正是为此保留注释写明Slicing a constant bool matrix triggers an MPSGraph compiler trap on this OSlaya_coreml/torch_model.py。但这并不能治愈一般的 RangeDim GPU 失败后续实验仍只匹配 49/63 且不可重复因此枚举长度仍是默认。复现已失败的 RangeDim cpu_gpu 配置运行时默认拒绝RangeDim cpu_gpu组合除非显式允许用于诊断实验laya_coreml/agent.py 会抛ValueError并提示allow_unvalidated_gpuTrue仅用于复现失败。文档给出了完整复现命令laya-coreml convert laya-multilingual models/range-experiment --shape-mode range python -m benchmarks.validate models/range-experiment \ --name laya-multilingual --compute-units cpu_gpu --allow-unvalidated-gpu \ --repeats 10 --output artifacts/range-experiment.json该测试在实测环境上预期失败。原始失败与成功报告都保留在benchmarks/results/中任何包含passed: false的报告都不得被引用为已验证配置。设备证据的边界CPU_AND_NE 不等于全在 ANE 上docs/CONVERSION.md特别澄清了一个容易误读的语义CPU_AND_NE表示允许 CPU 与 Neural Engine 参与不代表每个算子都运行在 Neural Engine 上。基准记录的是 Core ML 计算计划中偏好的/支持的设备与预估开销——这是一个预期计划而不是 Instruments 的运行时硬件 trace、功耗测量或独占 ANE 执行的证明。该口径同样延续到 docs/USAGE.mdcompute_unitscpu_ne只是允许 CPU 与 ANE 工作并不能保证每个操作都在 ANE 上执行把常规 SDPA 导出选成cpu_ne也不会让它变成专用 ANE 图。设备选项的映射集中在 laya_coreml/agent.pyall→ALL、cpu→CPU_ONLY、cpu_gpu→CPU_AND_GPU、cpu_ne→CPU_AND_NE。加载 Hub 快照symlink 权重文件修复发布冒烟测试发现了一个独立的打包问题从 Hugging Face 共享缓存加载符号链接权重文件时Core ML 的原生编译器会报缺失model.mlmodelc/weights/weight.bin。六个等效的本地 bundle 全部加载成功。修复方案是运行时先把 symlink 支持的包复制到常规文件的内容寻址缓存中再构造MLModel。实现细节在 laya_coreml/artifacts.py 的package_for_coreml()先对整个model.mlpackage树计算 SHA256tree_digest缓存根目录为~/.cache/laya-coreml/packages/可用环境变量LAYA_COREML_CACHE覆盖与 docs/USAGE.md 描述一致复制前后都校验哈希缓存被改动或损坏时直接报错Core ML cache integrity failure复用缓存时同样重新校验tree_digest普通文件的本地 bundle 不经过这条复制路径。哈希校验也延伸到了清单文件验证verify_files并防御..路径穿越laya_coreml/artifacts.py。顺带一提agent.py加载时会先校验coreml_config.json的format laya-coreml且format_version 1防止加载到不兼容格式laya_coreml/agent.py。可复现性coreml_config.json 清单与 golden reference每次导出都自带完整清单每个导出目录都包含coreml_config.json内容覆盖laya_coreml/convert.py原始权重 SHA256source_weights_sha256源 revision、形状batch_size、max_length、min_length16、default_length、max_options、flexible、mode、lengths精度precision、注意力实现attention、掩码构建方式attention_mask_construction工具版本coremltools、torch、numpy转换耗时conversion_seconds输出目录中每个文件的字节数与 SHA256files字段。导出器拒绝覆盖已存在目录导出失败时只清理自己新建的输出目录except BaseException: shutil.rmtree(output); raise保证不破坏已有成果。清单中的files字段与artifacts.verify_files配合可用于对任意 bundle 做端到端完整性验证。golden reference完全脱离 Transformers 的验证基准仓库提交的 golden reference 由未修改的上游 Laya revision573e5b62696ba441230cd6be71d593331b5d23af在 FP32 PyTorch MPS 上生成包含完整输入 token id 与未舍入的 logits。验证逻辑逐 token 精确比对并检查选中答案、校准概率、行动概率、token 计数与重复公开结果。由于验证基准已提交Core ML 验证可以完全不依赖 Transformers/PyTorch——正如 laya_coreml/agent.py 文件头注释所写No MLX, Transformers, or PyTorch dependency at runtime且 Transformers 既不是运行依赖也不是导出依赖。重新生成 golden reference 的命令来自文档git clone https://github.com/NandhaKishorM/laya .upstream git -C .upstream checkout 6a5819129eb220570792e417e49723d697efd76f python -m benchmarks.reference --upstream .upstream --model-root /path/to/original/checkpoints注意benchmarks/reference.py 中的UPSTREAM_REVISION常量为573e5b62696ba441230cd6be71d593331b5d23af脚本会用git rev-parse HEAD校验 clone 出的 commit不匹配则拒绝执行——若你按上述文档命令 checkout 的 revision 与脚本常量不一致需以脚本常量即生成已提交 golden reference 的 revision为准。参考脚本依赖的确切版本记录在生成的 JSON 中与钉死的导出环境相互独立。源码级实现深挖被转换的图长什么样docs/CONVERSION.md描述的是行为对齐而 laya_coreml/torch_model.py 给出了被转换图的具体形态可作为导出主题的最佳佐证显式模块化避免 Transformers 的 trace 期后端切换模型拆为Embeddingstoken embedding LayerNorm、Attention/HeadAttention多头注意力 RoPE、MLPGELU 门控、Layer/HeadLayer、Encoder、Head、DecisionModelstate-dict 命名与原始 Laya 检查点匹配。仅支持默认 RoPE非默认rope_type直接抛错full-attention 默认rope_theta160000、sliding-attention 默认10000cos/sin 表按max_length预计算并以非持久 buffer 注册。两种注意力实现sdpa用F.scaled_dot_product_attentionexplicit用matmul (q.shape[-1] ** -0.5)缩放 torch.where(mask, scores, -1e4)掩码 softmaxlaya_coreml/torch_model.py。导出时可通过--attention选择默认sdpa。局部窗口注意力window (positions[:, None] - positions[None, :]).abs() window // 2local_attention默认 128先切整数positions[:length]再构建布尔掩码正是第 5 条失败记录里的绕行方案。决策头type_emb3 类问题类型嵌入加到编码器输出marker_pos用torch.gather收集各选项标记处隐状态scorer是 LayerNorm→Linear→GELU→Linear 的 MLP无效选项被torch.full_like(logits, -1e4)掩掉。行动头的输入特征为(top1, top1-top2, 归一化熵, k/255)加上h[:, 0]CLS 位与 4 维决策特征拼接后过两层 MLP——这正是action_logits的来源。校准温度由运行时读取DecisionModel中注册了temperaturebuffer但实际应用的校准温度由 laya_coreml/common.py 的read_temperatures()从rl_agent_config.json读取并夹在[0.5, 5.0]TEMP_MIN/TEMP_MAX内——超出区间的温度如choice:11桶的 0.1006 会把 0.24 的概率锐化成 0.99会被拒绝应用并触发RuntimeWarning避免误导置信度调用方。上述实现全部有对应测试兜底tests/test_model.py且convert()中attention_mask_construction字段记录为integer_positions_v2把掩码如何构建也纳入了清单可追溯范围——这正是本文主题可复现导出的完整闭环。赞分享【免费下载链接】laya-coremlLocal Laya typed decisions on Apple Core ML and Neural Engine. Validated ports, ~5 ms short decisions on M3 Max, reproducible speed and energy benchmarks.项目地址https://gitcode.com/gh_mirrors/la/laya-coreml点击查看免费下载相关推荐如何把Laya权重导出为MLX检查点laya-mlx convert命令完整指南如何把Laya权重导出为MLX检查点laya mlx convert命令完整指南 laya mlx 是一个为 Apple Silicon 打造的本地 AI 推人工智能大模型本地部署推理引擎laya-coreml 真实终端演示录制指南用 Core ML ANE 驱动的贪吃蛇生成可分享 GIF/MP4 与可复现媒体laya coreml 真实终端演示录制指南用 Core ML ANE 驱动的贪吃蛇生成可分享 GIF/MP4 与可复现媒体 导读 本文面向希望把本地 A最完整指南YOLOv9模型导出到CoreML实现iOS实时目标检测最完整指南YOLOv9模型导出到CoreML实现iOS实时目标检测 引言iOS实时检测的痛点与解决方案 你是否还在为iOS设备上目标检测模型的性能问题发愁人工智能深度学习计算机视觉预训练创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表