[GH-ISSUE #6636] [Bug] Zero-tensor GGUF reports an unaligned tensor-data offset #4018

Closed
opened 2026-10-31 00:46:06 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @coygeek on GitHub (Oct 23, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/6636

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Evidence, artifacts, or reconstruction

Observed behavior

inspect-model-artifact successfully inspects a padded GGUF v3 fixture with zero tensors, but reports tensor_data_offset: 113 instead of 128. Offset 113 is the start of the 15 padding bytes, while the tensor-data section starts at the next 32-byte boundary. The same fixture also reproduced through ModelArtifactService.inspect. A one-tensor control reports the aligned offset correctly.

Reproduction

From a source checkout with the pinned dependencies and built CLI, create the exact tested zero-tensor fixture (only the destination path is normalized):

import struct

def string(value):
    data = value.encode()
    return struct.pack('<Q', len(data)) + data

def metadata(key, value):
    return string(key) + struct.pack('<I', 8) + string(value)

header = (b'GGUF' + struct.pack('<IQQ', 3, 0, 2)
          + metadata('general.architecture', 'llama')
          + metadata('tokenizer.ggml.model', 'gpt2'))
with open('/tmp/tokenizer.gguf', 'wb') as output:
    output.write(header + b'\0' * ((-len(header)) % 32))
node scripts/rea.mjs inspect-model-artifact /tmp/tokenizer.gguf --detail complete --json

The CLI and shared service each ran once for this fixture and once for the control. These are inert declaration fixtures; no model or tensor payload was executed, and they are not offered as runnable LLaMA models.

Expected behavior

Return tensor_data_offset: 128, retaining artifact.header_length: 113. The GGUF layout places alignment padding after tensor_infos and before tensor_data, including when the directory is empty: the format specification used by REA. REA's documentation separately excludes this padding from the header commitment.

Impact and scope

The reported layout gives an incorrect data-section boundary for zero-tensor GGUF files whose header is not aligned. Complete Evidence and summaries inherit the incorrect field. The observed case mislabels 15 padding bytes; it does not corrupt the input or mislocate any actual tensor. Real tokenizer-only files and other zero-tensor artifacts were not sampled. A practical workaround is to derive the boundary as Math.ceil(artifact.header_length / alignment) * alignment; that calculation produced 128 for the tested fixture.

REA version

6.7.0; source main revision a281455f0b83c088ea30ebbb887398888ed167fb.

Runtime and platform

Node.js v24.22.1; Linux x64. Locked dependencies and the source checkout's built CLI. No external analysis provider was used.

Target and artifact context

Source-built little-endian GGUF v3 with two string metadata entries, zero tensors, implicit 32-byte alignment, and 15 explicit zero padding bytes. Header length 113 bytes; total file length 128 bytes.

Interface

CLI

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

Both CLI commands exited 0 with empty stderr. Selected fields from their JSON results:

{"case":"zero-tensor","file_size":128,"header_length":113,"alignment":32,"tensor_data_offset":113,"tensors":0}
{"case":"one-tensor control","file_size":164,"header_length":151,"alignment":32,"tensor_data_offset":160,"tensors":1}

The control retained the same metadata and added one F32 tensor named weight, shape [1], relative offset 0, with four payload bytes. Its header ends at 151, padding ends at 160, and the reported tensor file offset is correctly 160. The production parser explicitly substitutes the unpadded reader position when tensorCount === 0: GgufHeader.ts. Evidence provenance: observed runtime output; the branch explanation is source-derived. No reproduction was rerun after writing this draft.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: A supported declaration inspection publishes an incorrect structural offset for the tested zero-tensor GGUF input; the error is bounded and does not affect existing tensor contents.
  • Workaround status: available
  • Workaround basis: The same result exposes header length and alignment, sufficient to calculate the correct 128-byte boundary for the observed fixture without changing the file.
Originally created by @coygeek on GitHub (Oct 23, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6636 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Evidence, artifacts, or reconstruction ### Observed behavior `inspect-model-artifact` successfully inspects a padded GGUF v3 fixture with zero tensors, but reports `tensor_data_offset: 113` instead of 128. Offset 113 is the start of the 15 padding bytes, while the tensor-data section starts at the next 32-byte boundary. The same fixture also reproduced through `ModelArtifactService.inspect`. A one-tensor control reports the aligned offset correctly. ### Reproduction From a source checkout with the pinned dependencies and built CLI, create the exact tested zero-tensor fixture (only the destination path is normalized): ```python import struct def string(value): data = value.encode() return struct.pack('<Q', len(data)) + data def metadata(key, value): return string(key) + struct.pack('<I', 8) + string(value) header = (b'GGUF' + struct.pack('<IQQ', 3, 0, 2) + metadata('general.architecture', 'llama') + metadata('tokenizer.ggml.model', 'gpt2')) with open('/tmp/tokenizer.gguf', 'wb') as output: output.write(header + b'\0' * ((-len(header)) % 32)) ``` ```sh node scripts/rea.mjs inspect-model-artifact /tmp/tokenizer.gguf --detail complete --json ``` The CLI and shared service each ran once for this fixture and once for the control. These are inert declaration fixtures; no model or tensor payload was executed, and they are not offered as runnable LLaMA models. ### Expected behavior Return `tensor_data_offset: 128`, retaining `artifact.header_length: 113`. The GGUF layout places alignment padding after `tensor_infos` and before `tensor_data`, including when the directory is empty: [the format specification used by REA](https://github.com/ggml-org/ggml/blob/da8e2a54b919557b816b1c2beb432ccb766f7ce0/docs/gguf.md#L297-L321). [REA's documentation](https://github.com/morluto/rea/blob/a281455f0b83c088ea30ebbb887398888ed167fb/docs/model-artifacts.md#L25-L30) separately excludes this padding from the header commitment. ### Impact and scope The reported layout gives an incorrect data-section boundary for zero-tensor GGUF files whose header is not aligned. Complete Evidence and summaries inherit the incorrect field. The observed case mislabels 15 padding bytes; it does not corrupt the input or mislocate any actual tensor. Real tokenizer-only files and other zero-tensor artifacts were not sampled. A practical workaround is to derive the boundary as `Math.ceil(artifact.header_length / alignment) * alignment`; that calculation produced 128 for the tested fixture. ### REA version 6.7.0; source main revision `a281455f0b83c088ea30ebbb887398888ed167fb`. ### Runtime and platform Node.js v24.22.1; Linux x64. Locked dependencies and the source checkout's built CLI. No external analysis provider was used. ### Target and artifact context Source-built little-endian GGUF v3 with two string metadata entries, zero tensors, implicit 32-byte alignment, and 15 explicit zero padding bytes. Header length 113 bytes; total file length 128 bytes. ### Interface CLI ### Earliest failure stage Native analysis or reconstruction ### Relevant output or evidence Both CLI commands exited 0 with empty stderr. Selected fields from their JSON results: ```json {"case":"zero-tensor","file_size":128,"header_length":113,"alignment":32,"tensor_data_offset":113,"tensors":0} {"case":"one-tensor control","file_size":164,"header_length":151,"alignment":32,"tensor_data_offset":160,"tensors":1} ``` The control retained the same metadata and added one F32 tensor named `weight`, shape `[1]`, relative offset 0, with four payload bytes. Its header ends at 151, padding ends at 160, and the reported tensor file offset is correctly 160. The production parser explicitly substitutes the unpadded reader position when `tensorCount === 0`: [GgufHeader.ts](https://github.com/morluto/rea/blob/a281455f0b83c088ea30ebbb887398888ed167fb/src/model/GgufHeader.ts#L386-L389). Evidence provenance: observed runtime output; the branch explanation is source-derived. No reproduction was rerun after writing this draft. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: A supported declaration inspection publishes an incorrect structural offset for the tested zero-tensor GGUF input; the error is bounded and does not affect existing tensor contents. - Workaround status: available - Workaround basis: The same result exposes header length and alignment, sufficient to calculate the correct 128-byte boundary for the observed fixture without changing the file.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#4018
No description provided.