资讯动态

Bonsai 2 27B MLX 包加载指南:解读 Prism Hadamard 运行时契约与 2-bit 三值权重解码

发布时间:2026/9/30 6:28:03 来源:尧图企业网站定制
大模型模型量化本地部署模型优化推理模型人工智能【免费下载链接】Ternary-Bonsai-2-27B-mlx-2bit项目地址https://ai.gitcode.com/hf_mirrors/prism-ml/Ternary-Bonsai-2-27B-mlx-2bit点击查看免费下载本篇技术指南围绕 PACK-RUNTIME.md 展开讲清楚一个核心问题为什么Ternary-Bonsai-2-27B-mlx-2bit这类折叠foldedHadamard 低比特权重包必须使用仓库自带的 bundled runtime 加载以及hadamard.json、config.json、runtime/目录中的加载器、验证文件之间如何构成一套完整的 Prism 运行时契约。读完本文你将掌握在 Apple Silicon 上正确加载该 2-bit/group-128 affine 权重包、运行文本生成与视觉问答、并理解重载验证与分词器验证边界的方法。为什么普通 MLX 加载器不能直接加载这个包PACK-RUNTIME.md的第一句话就点明了这个包的形态Text-only affine 2-bit/group-128 weights即按 128 个权重为一组、每组携带一个 FP16 scale 的仿射affine2-bit 量化权重。关键约束在于这批权重是在 Hadamard 旋转基下存储的——每个矩阵在量化前被按块block 1024做了正交 Hadamard 旋转旋转被离线折叠进存储权重中因此运行时必须在激活侧施加对应的变换否则输出是错的。文档明确指出Ordinary MLX loaders do not apply the required transforms.也就是说用mlx_lm.load()等常规路径加载这个包不会报错而是返回错误输出——因为config.json声明了model_type: prism_hadamard_qwen35标准加载器会把它当作普通 Qwen 检查点跳过激活变换与反向 embedding 查找导致静默错误。这也是 quickstart.py 中特别说明没有可安装的补丁版 mlx-lm的原因仓库自带 loader而不是去 patch 上游库。从 config.json 的尾部结构可以确认这套契约的落地形态schema_version: 2、model_type: prism_hadamard_qwen35、requires_runtime: runtime/artifact.py、hadamard_config: hadamard.json、tensor_namespace: mlx-vlm-qwen3_5以及components: {text: true, vision: true, mtp: false}。环境准备Apple Silicon 与依赖清单文档给出的安装要求十分明确在Apple Silicon上安装runtime/requirements.txt中的依赖。该文件锁定了精确版本便于复现mlx0.32.0 mlx-lm0.31.3 numpy2.0 tokenizers0.21 jinja23.1 mlx-vlm0.6.3 transformers5.5.0 pillow10.0安装方式假定已将仓库下载到本地目录pip install -r runtime/requirements.txt这里有一处需要结合当前仓库状态澄清的细节PACK-RUNTIME.md写于 preview 阶段提到 Vision and MTP are not included。但当前仓库的 config.json 中components.vision为true并带有完整的vision_config27 层、hidden_size 1152、patch_size 16 的 Qwen 视觉塔以 FP16 原样携带仓库同时提供了 runtime/vision_artifact.py 用于视觉加载。因此当前包实际同时携带语言模型与视觉塔纯文本推理不需要视觉塔驻留MTP多 token 预测则确实未包含mtp: false。文本模型加载artifact.load_model 与 Packed 模块PACK-RUNTIME.md给出的核心加载代码为import sys sys.path.insert(0, /path/to/pack/runtime) from artifact import load_model model, config load_model(/path/to/pack)这里/path/to/pack/runtime与/path/to/pack在本仓库中分别对应 runtime/ 目录与仓库根目录。load_model的实现位于 runtime/artifact.py其流程可以拆解为四个步骤校验 schema读取config.json要求schema_version 1且model_type prism_hadamard_qwen35否则抛Unsupported packed model schema构建骨架用text_confighidden_size 5120、64 层、full_attention_interval 4 等实例化mlx_lm.models.qwen3_5.TextModel逐个替换为 Packed 模块遍历config[modules]中的 402 条记录reload-validation.json 中的packed_modules: 402与之对应为每条路径从model.safetensors中取回weight、scales、biases三组张量校验形状与 dtype 后构造Packed模块并挂载到对应层严格装载剩余权重model.load_weights(..., strictTrue)装载所有非折叠权重然后model.eval()。Packed模块定义在 runtime/runtime.py它是整个契约的执行核心。前向过程按embedding标志分两条路径非 embedding 路径若该模块声明了blockHadamard 块大小先对激活执行fwht(x, block, signs)runtime/runtime.py即先乘显式符号向量、再做归一化 Hadamard 变换scale1/sqrt(block)随后调用mx.quantized_matmul以group_size128, bits2直接消费打包权重embedding 路径对应model.embed_tokensconfig.json 中embedding: true先用mx.dequantize恢复查表行再施加逆Hadamard 变换fwht(..., inverseTrue)——这正是文档强调的反向 embedding 查找变换。值得注意的实现细节是Packed直接存储weight、scales、biases三个 MLX 数组权重本身是mx.uint32打包的 2-bit 码字推理时从不展开回 FP16 稠密矩阵这与 README 中packed weights are consumed directly的描述一致。仿射 2-bit 格式与 Prism contract v1PACK-RUNTIME.md对hadamard.json的说明值得逐句拆解hadamard.jsonuses the version-1 Prism contract accepted by MLX Swifts PrismHadamardConfiguration.hadamard.json 的开头字段即为契约版本与几何定义{ prism.hadamard.version: 1, prism.hadamard.block_size: 1024, prism.hadamard.transform: normalized-sylvester-walsh-hadamard, prism.hadamard.axis: input-last-dimension, prism.hadamard.sign_mode: explicit, ... }这些字段与 runtime/runtime.py 中 GGUF 加载器的校验逻辑一一对应block只接受 512/1024/2048/4096sign_mode必须为explicit显式符号向量sign_widths声明符号向量的宽度本包为 5120、6144、17408 三档sign_values提供逐元素 ±1 的符号序列且加载时会校验np.isin(a, [-1, 1]).all()。文档强调的第二点是命名空间Names refer to the saved MLX tensor namespace.即hadamard.json中prism.hadamard.weight_names与prism.hadamard.inverse_weight_names里列出的名称指向的是model.safetensors中保存的 MLX 张量名本包为language_model.*前缀对应tensor_namespace: mlx-vlm-qwen3_5。被折叠的矩阵包括语言模型的lm_head、各层线性注意力in_proj_qkv、in_proj_z、out_proj、全注意力q/k/v/o_proj与 MLPgate/up/down_proj而model.embed_tokens.weight单独列入inverse_weight_names需要在运行时施加逆变换。文档的第三点是一个重要的易错提醒GDN activations are already grouped in the bundled runtime; do not permute them again.GDNlinear-attention 输出门控相关激活在本 bundled runtime 中已经按分组排布config.json尾部gdn_activation_layout: grouped也确认了这一点因此下游使用者不应再次做 permute。这与 runtime/runtime.py 中的检查一致若 GDN 输出不是分组折叠gdn_v_grouped为假且nv ! nk加载器会直接拒绝加载未实现的非分组情形。文档还预告了 Swift 侧的边界Swift full-model loading still requires model integration; layer support alone is insufficient.即 MLX Swift 目前能通过PrismHadamardConfiguration接受这份 version-1 契约对应层级的支持但完整的 Swift 全模型加载仍需要模型集成工作仅有层支持是不够的。视觉加载vision_artifact 与 chat_config虽然PACK-RUNTIME.md只给出了文本加载路径但当前仓库实际携带视觉塔README.md 的 Quickstart 也提供了完整的视觉加载示例。对应的实现位于 runtime/vision_artifact.pyimport sys sys.path.insert(0, bonsai2-27b-mlx/runtime) from vision_artifact import load_vl_model, chat_config from mlx_vlm import generate from mlx_vlm.prompt_utils import apply_chat_template model, processor, config load_vl_model(bonsai2-27b-mlx) prompt apply_chat_template(processor, chat_config(config), What is in this image?, num_images1) print(generate(model, processor, prompt, [photo.jpg], max_tokens256, temperature1.0, top_p0.95, top_k20))load_vl_model与load_model的关键差异在于它校验components.vision必须为真且base_model_type qwen3_5然后构建mlx_vlm.models.qwen3_5.Model把Packed模块安装进language_model的对应路径runtime/vision_artifact.py视觉塔本身是未旋转、未量化的官方 Qwen FP16 塔27 层、0.92 GB直接按普通权重装载无需任何 Hadamard 变换build_processor显式选用 PIL 后端的Qwen2VLImageProcessorPil与Qwen3VLProcessor整条路径只依赖 numpy 与 Pillow无需 torch它还会读取generation_config.json中的eos_token_id本包为[248046, 248044]即|im_end|与|endoftext|把停止条件写入 processor与 llama.cpp 行为对齐。其中chat_config(config)runtime/vision_artifact.py的作用文档已有说明mlx-vlm 的 prompt 助手依赖model_type字段而包的model_type被刻意设置为自定义值prism_hadamard_qwen35所以要把model_type改回基础类型qwen3_5图像 token 才能正确落位。同时注意不传图片即为纯文本使用。一键验证quickstart.py 与采样参数仓库提供了一键验证脚本 quickstart.pypython quickstart.py your prompt它的内部逻辑值得了解quickstart.py从generation_config.json读取采样参数并显式传入sampler——因为 mlx-lm 与 mlx-vlm 都不会自动读取该文件不传则退化为贪心解码。本包的 generation_config.json 内容为{ bos_token_id: 248044, do_sample: true, eos_token_id: [248046, 248044], pad_token_id: 248044, temperature: 1.0, top_k: 20, top_p: 0.95 }脚本还会用 chat_template.jinja 渲染提示词默认enable_thinkingFalse、不注入 reasoning effort 指令并基于eos_token_id与|im_end|、|endoftext|构建停止集合逐 token 解码直到命中停止符。README 中推荐的两组采样参数Thinking Modetemperature1.0, top_p0.95, top_k20, min_p0.0, presence_penalty0.0, repetition_penalty1.0Instruct 模式temperature0.7, top_p0.80, top_k20, min_p0.0, presence_penalty1.5, repetition_penalty1.0也正是generation_config.json与 GGUF 元数据中携带的默认值。此外模型默认使用xhighreasoning effortmedium可换取更短回答low不受支持选择后行为接近xhigh。验证文件的边界reload-validation 与 tokenizer-validationPACK-RUNTIME.md对两个验证文件的定位做出了精确的边界声明这是防止误读的关键Reload validation checks serialization, not model quality or cross-runtime equivalence.仓库中的 reload-validation.json 记录了save_and_verify的产物{ reload_logits_exact: true, checked_logits: 248320, packed_modules: 402 }对应 runtime/artifact.py 中的save_and_verify保存后重新加载对同一组input_ids分别计算原模型与重载模型的 logits用np.testing.assert_array_equal断言逐位相等。这只证明序列化 → 反序列化过程无损、加载器还原了保存时的数值不证明模型质量也不证明跨运行时如与 llama.cpp / Swift的等价性。Tokenizer validation checks vocabulary IDs and BPE merge ranks; it does not certify pre-tokenizer behavior.tokenizer-validation.json 记录{ vocabulary_ids_match: true, bpe_merges_match: true }它只覆盖词表 ID 与 BPE merge 排名的一致性不担保 pre-tokenizer预分词器行为——即对同一段原始文本切分出的 token 序列可能因预分词规则差异而不同。此外The chat template is copied from the source GGUF.即 chat_template.jinja 是直接从源 GGUF 复制的它与上游保持一致支持系统消息、图像/视频占位符、think推理块、工具调用格式与 reasoning effort 指令xhigh/medium/low但这份复制本身不代表模板经过独立评测。契约边界与实操注意事项汇总综合PACK-RUNTIME.md与仓库实现加载本包时有四条边界必须牢记必须使用 bundled runtime。load_model/load_vl_model会严格校验model_type、schema 版本、张量形状与 dtype、符号向量合法性runtime/artifact.py不匹配即抛错而普通 loader 不校验只会静默产出错误输出比报错更危险不要在 bundled runtime 之外再次 permute GDN 激活仓库中的打包格式2-bit 码字 FP16 scale/bias已按 group 128 排布好验证文件有明确语义边界reload-validation只证序列化无损tokenizer-validation只证词表与 merge 一致chat template 只是从 GGUF 原样搬运Swift 侧目前只到契约解析/层支持完整全模型加载仍需模型集成若需 llama.cppCUDA/Metal/CPU或 Swift 全模型体验应使用同权重的 GGUF 打包版本。另外本包当前携带视觉塔components.vision: true纯文本任务走artifact.load_model带图任务走vision_artifact.load_vl_model两者共用同一套Packed内核与 Prism contract v1 元数据MTP 组件未包含mtp: false。对希望进一步研究实现的读者建议从 runtime/runtime.py 的fwht/Packed、runtime/codec.py 的transcodeGGUF PQ2_0/PTQ1_0 到 MLX affine 2-bit 的无损转码以及 runtime/artifact.py 的save_model/load_model三份源码入手它们共同构成了这份 Prism Hadamard 运行时契约的完整闭环。赞分享大模型模型量化本地部署模型优化推理模型人工智能【免费下载链接】Ternary-Bonsai-2-27B-mlx-2bit项目地址https://ai.gitcode.com/hf_mirrors/prism-ml/Ternary-Bonsai-2-27B-mlx-2bit点击查看免费下载相关推荐Ternary-Bonsai-2-27B-mlx-2bit自定义MLX运行时深度解析Packed模块如何直接消费2-bit打包权重Ternary Bonsai 2 27B mlx 2bit自定义MLX运行时深度解析Packed模块如何直接消费2 bit打包权重 Ternary Bonsa大模型模型量化本地部署模型优化推理模型人工智能Hadamard旋转如何让三元量化可行Ternary-Bonsai-2-27B-mlx-2bit权重旋转核心原理剖析Hadamard旋转如何让三元量化可行Ternary Bonsai 2 27B mlx 2bit权重旋转核心原理剖析 Ternary Bonsai 2 27B大模型模型量化本地部署模型优化推理模型人工智能破解三元比特流Ternary-Bonsai-2-27B-mlx-2bit的PTQ1_0/PQ2_0到MLX 2-bit无损转码算法详解破解三元比特流Ternary Bonsai 2 27B mlx 2bit的PTQ1_0/PQ2_0到MLX 2 bit无损转码算法详解 在开源项目 Terna大模型模型量化本地部署模型优化推理模型人工智能创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑