news 2026/9/24 14:53:27

OpenJarvis Pearl 工具链解析:从 Hugging Face safetensors 到 Pearl 量化检查点的本地转换

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OpenJarvis Pearl 工具链解析:从 Hugging Face safetensors 到 Pearl 量化检查点的本地转换

【免费下载链接】OpenJarvis

Personal AI, On Personal Devices

项目地址:https://gitcode.com/gh_mirrors/op/OpenJarvis
点击查看免费下载

Pearl Tooling(scripts/pearl/README.md)是 OpenJarvis 中一组独立于运行时、面向模型 enablement 与验证的 Pearl 生态工具,其核心是model_converter.py——一个把原始 Hugging Face safetensors 权重转换为 Pearl vLLM 插件可消费的量化暂存检查点的实验性脚本。本文围绕该目录的定位、转换脚本的量化策略、配置文件与命令行用法展开,并结合仓库源码与测试用例,说明如何在本地把原始模型加工成 Pearl 兼容的 staging artifact,以及它与src/openjarvis/mining/运行时提供方之间的边界。

Pearl Tooling 目录的定位与设计边界

在 OpenJarvis 仓库中,scripts/pearl/被明确界定为"独立于 OpenJarvis 运行时的 Pearl 生态工具"。这份定位意味着该目录内的脚本满足两个约束:

  • 服务于模型 enablement 或验证阶段,而不是作为守护进程、挖矿循环等运行时组件被自动加载;
  • 由开发者手动显式运行,是操作性工具(operational tools),不是面向最终用户的功能入口。

该目录在架构上承担的是"开发期工具"角色,与之相对的运行时代码路径在文档中被明确划界:

  • 面向用户的挖矿命令(user-facing mining commands)位于 src/openjarvis/cli/;
  • 挖矿运行时提供方(runtime provider code)位于 src/openjarvis/mining/;
  • scripts/pearl/只保留需要开发者手工触发的转换、验证类脚本。

也就是说,一个完整的 Pearl 挖矿能力由三层拼成:CLI 命令层(jarvis minejarvis pearl)、运行时提供方层(VllmPearlProvider等,见 src/openjarvis/mining/vllm_pearl.py),以及本目录提供的模型加工工具层。model_converter.py属于第三层,它的产出是"实验性 Pearl 兼容暂存检查点",而非已通过的验证模型。

model_converter.py:脚本能做什么,不能做什么

model_converter.py(scripts/pearl/model_converter.py)是一个约 360 行的独立 Python 工具,其文档字符串(docstring)对该工具的职责与边界做了严格声明:

它做什么:

  • 把原始 Hugging Face safetensors 检查点转换为 Pearl vLLM 插件所需的量化形态;
  • 对挖矿层(mining layers)输出 int7 通道级(channel-wise)权重;
  • 对非挖矿层(non-mining layers)输出 int8 通道级权重;
  • 写入动态的、按 token 粒度对称的激活量化元数据(dynamic token-wise symmetric activation metadata)。

它不做什么("intentionally conservative"):

  • 不向 Hugging Face 上传任何产物;
  • 不把任何模型标记为已验证(validated);
  • 目标收敛于 Gemma4/Qwen3.5 的 enablement 工作,因此行为刻意保守。

这个边界与 docs/development/pearl-model-enablement.md 中的模型 enablement 流程一致:转换器产出的 staging artifact 必须继续经过jarvis mine inspect-modeljarvis mine validate-model在 H100/H200 硬件上验证,通过后才能被提升为validated状态。

为了方便从scripts/mining/一侧引用,仓库还提供了一个兼容包装器 scripts/mining/pearl_model_converter.py,它通过runpy.run_path直接执行scripts/pearl/model_converter.py,实现逻辑单一来源、不复制代码。

权重分类:哪些层被量化、哪些层被跳过

转换的核心逻辑是classify_weight(name, tensor)(scripts/pearl/model_converter.py),它把 safetensors 里的每个张量分为三类:copied(原样复制)、mining(int7 量化)、non_mining(int8 量化)。

分类规则由三个正则表达式决定:

正则匹配目标分类结果
NON_MINING_REself_attn.(q_proj\|k_proj\|v_proj\|qkv_proj).weightmlp.down_proj.weightnon_mining→ int8
IGNORED_TEXT_REembed_tokensembed_tokens_per_layerlm_head、各类norm/layernorm.weightcopied→ 原样保留
IGNORED_MULTIMODAL_REmodel.vision/model.audio/embed_visionvision_towervision_modelvisualaudiocopied→ 原样保留

此外,任何不以.weight结尾或不是 2 维(ndim != 2)的张量也一律归为copied。这保证了 embedding、LayerNorm、lm_head 以及多模态子模型不进入量化路径,保留原始精度——因为 Pearl 的挖矿量化只面向文本侧线性层。

分类依据在 tests/pearl/test_model_converter.py 中有明确断言:在构造的TinyForCausalLM检查点中,q_proj被记为non_miningo_proj被记为mining,而embed_tokensembed_tokens_per_layerinput_layernorm保持 bfloat16 原样且不生成对应的weight_scale

量化内核:对称 per-output-channel int 量化

真正执行量化的是quantize_channelwise(weight, *, max_val, device, chunk_rows)(scripts/pearl/model_converter.py)。它是一个对称的、按输出通道(行)进行的 int 量化,实现要点如下:

  1. chunk_rows(默认 4096)分块处理,控制内存峰值;
  2. 每块先转 float32 计算行方向绝对值的最大值:scale = chunk.abs().amax(dim=1, keepdim=True) / max_val
  3. 零行(全零通道)的 scale 被置为 1,避免除零;
  4. 量化公式为torch.round(chunk / scale).clamp(-max_val, max_val),输出 int8 张量(int7 也以 int8 存储,只是值域被 clamp 到 ±63);
  5. scale 以 bfloat16 保存,最终与量化权重一同写入,命名为{权重名去掉 .weight}.weight_scale

两个量化档位的max_val由分类决定:mining 层为63(即 int7 的 ±2⁶−1),non-mining 层为127(int8 的 ±2⁷−1)。测试断言了量化后权重 dtype 为torch.int8,且weight_scale形状为(rows, 1)——这正是 Pearl/vLLM 插件按通道反量化的输入格式。

quantization_config:mixed-precision 的 Pearl 元数据

转换完成后,脚本会通过patch_config()在输出目录的config.json中注入quantization_config,声明量化方式为"quant_method": "pearl"(版本0.13.0,状态"compressed")。这份配置(scripts/pearl/model_converter.py)是 vLLM 插件识别该检查点的关键,核心结构如下:

  • config_groups.group_0format = "int-quantized",权重为 int8 通道级量化(strategy: "channel"symmetric: trueobserver: "minmax"),输入激活为 int8 动态按 token 量化(dynamic: truestrategy: "token"),targets用正则锁定self_attn的 q/k/v/qkv_proj 与down_proj——对应非挖矿层;
  • config_groups.group_1format = "int-quantized",权重为 int7 通道级量化(num_bits: 7),输入激活为 int7 动态按 token 量化,targets["Linear"]——兜底覆盖其余文本线性层,即挖矿层;
  • ignore列表:以正则排除lm_headembed_tokensembed_tokens_per_layervision*visual*vision_towerimage*audio*embed_visionmulti_modal_projector等,与classify_weight中的IGNORED_TEXT_RE/IGNORED_MULTIMODAL_RE一一对应;
  • kv_cache_scheme: Nonesparsity_config: {}transform_config: {}global_compression_ratio: None:表示仅做 weight+activation 量化,不做 KV cache 量化和稀疏化。

测试同样验证了这份配置的关键字段:quant_method == "pearl"group_1.weights.num_bits == 7,以及 ignore 列表包含re:.*visual.*re:.*embed_tokens_per_layer$

元数据与多模态兼容:Gemma4 的 preprocessor 处理

除权重转换外,脚本还处理两件容易被忽略的元数据工作:

  1. copy_metadata_files():把源目录下所有非.safetensors文件(*.json*.jinja*.txt*.model.gitattributes等)原样复制到输出目录,保证 tokenizer、processor、generation 配置等随检查点一起分发;
  2. patch_processor_metadata():针对 Gemma4 架构(architectures中含"Gemma4"的模型)做 vLLM profiler 兼容处理——如果输出目录存在processor_config.json但缺少preprocessor_config.json,则复制一份同名文件。原因在 docs/development/pearl-model-enablement.md 中有说明:vLLM 的 Gemma4 多模态 profiler 需要这部分处理器元数据。该行为有独立测试用例覆盖(tests/pearl/test_model_converter.py)。

转换完成后,脚本还会写出model.safetensors.index.json(含total_size与排序后的weight_map),这是多分片 safetensors 模型被 vLLM 正确加载所必需的索引文件。

命令行用法与完整转换流程

脚本入口是标准的argparseCLI,核心参数如下:

参数说明默认值
source(位置参数)本地模型目录,或 Hugging Face 模型 id必填
output_dir(位置参数)输出检查点目录必填
--hf-token-env读取 Hugging Face token 的环境变量名HF_TOKEN
--device量化计算设备cpu(可指定cuda
--chunk-rows通道量化分块行数,控制内存峰值4096
--dry-run只做分类统计、不写任何检查点false

source解析逻辑(resolve_source())很实用:如果参数是已存在的本地路径则直接使用;否则走huggingface_hub.snapshot_download下载快照,且只拉取*.json*.jinja*.txt*.model*.safetensors.gitattributes这几类文件,token 通过--hf-token-env指定的环境变量提供(默认HF_TOKEN),因此可以转换 gated 模型。

一个典型的转换命令(同样出现在 docs/development/pearl-model-enablement.md 的 enablement 清单中):

python scripts/pearl/model_converter.py \ meta-llama/Llama-3.1-8B-Instruct \ /tmp/pearl-ai-Llama-3.1-8B-Instruct-pearl \ --device cuda

在正式执行前,建议先跑一遍--dry-run做分类审计,确认 mining/non-mining 层的划分符合预期、不会产生误伤:

python scripts/pearl/model_converter.py \ meta-llama/Llama-3.1-8B-Instruct \ /tmp/pearl-ai-Llama-3.1-8B-Instruct-pearl \ --device cuda --dry-run

--dry-run下每个.safetensors文件都会打印copied=... mining=... non_mining=...三类计数,最后汇总total: copied=... mining=... non_mining=...并提示"dry run only; no checkpoint was written"。

转换器对每个 safetensors 分片都输出进度统计,整个流程的产出物包括:

  • 量化后的.safetensors分片 + 每个量化权重对应的*_weight_scale张量;
  • 注入quantization_configconfig.json
  • 完整复制过来的 tokenizer/processor 等元数据文件(Gemma4 额外生成preprocessor_config.json);
  • model.safetensors.index.json索引文件。

从 staging artifact 到可挖矿模型

必须强调的是:转换器的输出只是staging artifact,不是可对外宣称的验证模型。OpenJarvis 只支持pearl-aiHugging Face 组织发布的 Pearl 模型作为面向用户的挖矿模型(见 docs/development/pearl-model-enablement.md 的 Supported Models 列表),本地转换产物的完整路径是:

  1. jarvis mine inspect-model --model /tmp/pearl-ai-...-pearl检查本地 staging 检查点;
  2. jarvis mine init --provider vllm-pearl --model <pearl-ai 模型 id> --local-model-path <本地检查点目录> --vllm-arg=--language-model-only --vllm-arg=--skip-mm-profiling配置 Docker 挖矿;
  3. jarvis mine start启动,并经过 vLLM 加载、NoisyGEMM 提交候选证明、gateway 指标等验收标准(见 docs/development/pearl-model-enablement.md 的 Acceptance Criteria)后,模型才可能在注册表(src/openjarvis/mining/_models.py)中从planned提升为validated

也就是说,model_converter.py解决的是"怎么把原始权重变成 Pearl 插件认识的形态",而"这个模型能不能正式开放挖矿"由 docs/development/pearl-model-enablement.md 定义的多阶段验证流程说了算。这也正是scripts/pearl/作为"enablement 或验证阶段工具"的存在意义:它把最繁琐的量化与元数据加工自动化,让模型启用工作聚焦在真正需要硬件验证的环节上。

小结

scripts/pearl/目录是 OpenJarvis Pearl 挖矿能力链上的"加工车间":model_converter.py以明确的保守策略,把原始 Hugging Face safetensors 检查点转换为 int7/int8 混合精度、带动态 token 级激活量化的 Pearl 兼容 staging artifact,并同步处理好 config、元数据、索引与 Gemma4 兼容文件。配合 tests/pearl/test_model_converter.py 的单元测试与 docs/development/pearl-model-enablement.md 的 enablement 流程,开发者可以完整复现"原始模型 → 本地转换 → 本地 inspect → Docker 挖矿验证"的模型启用工作流,而不会误把 staging 产物当作已验证的正式发布模型。

【免费下载链接】OpenJarvis

Personal AI, On Personal Devices

项目地址:https://gitcode.com/gh_mirrors/op/OpenJarvis
点击查看免费下载
上一篇:数据库顶会追踪终极指南:ccf-deadlines覆盖SIGMOD/VLDB/KDD最新动态
下一篇:TypeGraphQL订阅消息认证刷新策略:无缝续期

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 14:49:43

Argos Translate:一条命令安装,快速上手离线多语言翻译

Argos Translate&#xff1a;一条命令安装&#xff0c;快速上手离线多语言翻译 【免费下载链接】argos-translate Open-source offline translation library written in Python 项目地址: https://gitcode.com/GitHub_Trending/ar/argos-translate Argos Translate 是一…

作者头像 李华
网站建设 2026/9/24 14:48:15

Zonotope几何建模:虚拟电厂分布式资源不确定性聚合方法

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华