【免费下载链接】OpenJarvis
Personal AI, On Personal Devices
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 mine、jarvis 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-model与jarvis 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_RE | self_attn.(q_proj\|k_proj\|v_proj\|qkv_proj).weight、mlp.down_proj.weight | non_mining→ int8 |
IGNORED_TEXT_RE | embed_tokens、embed_tokens_per_layer、lm_head、各类norm/layernorm的.weight | copied→ 原样保留 |
IGNORED_MULTIMODAL_RE | model.vision/model.audio/embed_vision、vision_tower、vision_model、visual、audio等 | copied→ 原样保留 |
此外,任何不以.weight结尾或不是 2 维(ndim != 2)的张量也一律归为copied。这保证了 embedding、LayerNorm、lm_head 以及多模态子模型不进入量化路径,保留原始精度——因为 Pearl 的挖矿量化只面向文本侧线性层。
分类依据在 tests/pearl/test_model_converter.py 中有明确断言:在构造的TinyForCausalLM检查点中,q_proj被记为non_mining、o_proj被记为mining,而embed_tokens、embed_tokens_per_layer、input_layernorm保持 bfloat16 原样且不生成对应的weight_scale。
量化内核:对称 per-output-channel int 量化
真正执行量化的是quantize_channelwise(weight, *, max_val, device, chunk_rows)(scripts/pearl/model_converter.py)。它是一个对称的、按输出通道(行)进行的 int 量化,实现要点如下:
- 按
chunk_rows(默认 4096)分块处理,控制内存峰值; - 每块先转 float32 计算行方向绝对值的最大值:
scale = chunk.abs().amax(dim=1, keepdim=True) / max_val; - 零行(全零通道)的 scale 被置为 1,避免除零;
- 量化公式为
torch.round(chunk / scale).clamp(-max_val, max_val),输出 int8 张量(int7 也以 int8 存储,只是值域被 clamp 到 ±63); - 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_0:format = "int-quantized",权重为 int8 通道级量化(strategy: "channel"、symmetric: true、observer: "minmax"),输入激活为 int8 动态按 token 量化(dynamic: true、strategy: "token"),targets用正则锁定self_attn的 q/k/v/qkv_proj 与down_proj——对应非挖矿层;config_groups.group_1:format = "int-quantized",权重为 int7 通道级量化(num_bits: 7),输入激活为 int7 动态按 token 量化,targets为["Linear"]——兜底覆盖其余文本线性层,即挖矿层;ignore列表:以正则排除lm_head、embed_tokens、embed_tokens_per_layer、vision*、visual*、vision_tower、image*、audio*、embed_vision、multi_modal_projector等,与classify_weight中的IGNORED_TEXT_RE/IGNORED_MULTIMODAL_RE一一对应;kv_cache_scheme: None、sparsity_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 处理
除权重转换外,脚本还处理两件容易被忽略的元数据工作:
copy_metadata_files():把源目录下所有非.safetensors文件(*.json、*.jinja、*.txt、*.model、.gitattributes等)原样复制到输出目录,保证 tokenizer、processor、generation 配置等随检查点一起分发;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_config的config.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 列表),本地转换产物的完整路径是:
- 用
jarvis mine inspect-model --model /tmp/pearl-ai-...-pearl检查本地 staging 检查点; - 用
jarvis mine init --provider vllm-pearl --model <pearl-ai 模型 id> --local-model-path <本地检查点目录> --vllm-arg=--language-model-only --vllm-arg=--skip-mm-profiling配置 Docker 挖矿; 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
相关推荐
OpenJarvis Pearl 模型启用指南:从 Hugging Face 原模型到 vLLM 可挖矿 Pearl 模型的完整流程
OpenJarvis Pearl 模型启用指南:从 Hugging Face 原模型到 vLLM 可挖矿 Pearl 模型的完整流程 导读 本指南基于 docs
OpenJarvis 在 Apple Silicon 上挖掘 Pearl 链:cpu-pearl 与 apple-mps-pearl 实战指南
OpenJarvis 在 Apple Silicon 上挖掘 Pearl 链:cpu pearl 与 apple mps pearl 实战指南 OpenJarv
OpenJarvis Pearl CLI 集成指南:`jarvis pearl` 原生节点、钱包与 RPC 工具透传实战
OpenJarvis Pearl CLI 集成指南: jarvis pearl 原生节点、钱包与 RPC 工具透传实战 jarvis pearl 是 OpenJ
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考