diff --git a/CMakeLists.txt b/CMakeLists.txt index 79a6b1c44..417ef980b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -331,6 +331,11 @@ add_test(NAME bench_preflight COMMAND bash ${CMAKE_SOURCE_DIR}/tools/tests/test- # engine#1702: builds a per-layer MoE expert placement table from a moe_trace, and refuses a prefill-only trace because # placement is a decode lever (5.4-6.9 % on batched prefill against dedup's 90-94 %). --self-test drives it on synthetic # traces with a known answer; no model, no device. +# engine#1934: reading ONE tensor out of a safetensors shard needs `data_offsets` measured from 8 + header_len, not +# from byte 8. Getting that wrong returns a *different* tensor of the same size that still looks finite, and it cost +# two false conclusions about a pack in one night. `--self-test` drives the rule on a synthetic shard (no network): +# the same offset from the data section returns the tensor, from byte 8 it does not. +add_python_test(hf_tensor_self ${CMAKE_SOURCE_DIR}/tools/hf_tensor.py --self-test) add_python_test(moe_placement ${CMAKE_SOURCE_DIR}/tools/moe_placement.py --self-test) # engine #1279: the version a package is built with (scripts/pack-version.sh) -- a release tag as # it stands, a candidate mapped into the ISO week of its own date with a suffix that sorts below that diff --git a/tools/hf_tensor.py b/tools/hf_tensor.py new file mode 100755 index 000000000..57f9b4b59 --- /dev/null +++ b/tools/hf_tensor.py @@ -0,0 +1,213 @@ +#!/usr/bin/env python3 +# Copyright 2026 bong-water-water-bong +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""hf_tensor.py -- read ONE tensor out of a safetensors shard, over HTTP range requests. + +Written because I got a safetensors offset wrong four times in one night and each time concluded something +false about a pack. The rule that bit me, and the only reason this file exists: + + a safetensors `data_offsets` entry is relative to the START OF THE DATA SECTION, i.e. `8 + header_len` + bytes into the file -- not to byte 8. + +Fetch `bytes=8+off` and you get a slice of whatever tensor is 11,656 B (this shard's header) away from the one +you asked for, which still *looks* like a tensor: it has a plausible size, it is finite, and a correlation +against it is a correlation against noise. Two of those cost me a retraction on a merged PR. + +So this tool does the arithmetic once, prints the tensor's own statistics so a wrong read is visible rather +than plausible (a norm gain is ~1.0, not +-0.03), and can write the raw bytes for a comparison script. + +usage: + tools/hf_tensor.py --repo tencent/Hunyuan-7B-Instruct \ + --tensor model.layers.0.self_attn.query_layernorm.weight [--out q.bin] [--json] + tools/hf_tensor.py --self-test + +Exit: 0 ok, 1 the tensor or shard was not found, 2 cannot tell (no network / not a safetensors repo). +""" + +import argparse +import json +import pathlib +import struct +import sys +import urllib.request + +UA = {"User-Agent": "1bit-aba/hf_tensor"} # HF rejects the default python urllib agent on some endpoints +DTYPE_TABLE = { + "F64": ("