Skip to content

docs(MODEL-MM-dots3-note): W0.5 — Thor is a CUDA host now, and its baseline caught a segfault on main (#699, #955, #960) - #956

Open
localai-bot wants to merge 1 commit into
mainfrom
row/dots3-note-w0.5-thor
Open

docs(MODEL-MM-dots3-note): W0.5 — Thor is a CUDA host now, and its baseline caught a segfault on main (#699, #955, #960)#956
localai-bot wants to merge 1 commit into
mainfrom
row/dots3-note-w0.5-thor

Conversation

@localai-bot

Copy link
Copy Markdown
Collaborator

W0.5 of the dots3-note row (#699), the first dispatchable task under §6.4 option B. Docs and records only — no src/, no include/, no tests/. Issues: #699 (the row) and #955 (the sm_110 baseline this opens).

What was done on Thor

192.168.68.23 now builds vllm.cpp with CUDA ON for sm_110, runs kernels on the device, and has a recorded ctest baseline. The recipe is in .agents/environment.md so the next agent does not repeat the archaeology.

Container, not a host toolchain, and the reason is measured. / on Thor is a read-only 4.4 G ext2 loop (/dev/loop0, 1.3 G free) — it is an immutable Kairos image, so apt install into / is not available at all. A /home-prefix CUDA runfile would work but has to be re-derived after every reimage; the container carries the toolchain in one pinned digest and the NVIDIA runtime injects the host driver.

The image is a 4-line Dockerfile on nvidia/cuda@sha256:7d2f6a8c2071… (pinned by digest — the 13.0.1 tag moves) plus cmake ninja-build git python3 python3-dev ca-certificates shellcheck. Inside: nvcc 13.0.88, cmake 3.28.3, ninja 1.11.1. Every invocation needs --runtime=nvidia, -e NVIDIA_DISABLE_REQUIRE=1 and sudo -n.

That last point corrects a script already on the box: /home/mudler/_build_thor.sh states the container runtime "REFUSES this image on its driver" and drops --runtime on that basis. It is wrong, and it is wrong only because it also drops NVIDIA_DISABLE_REQUIRE=1.

Proof the build is really a CUDA build

A build that quietly disables CUDA is the failure mode this task exists to catch, so it is checked three independent ways:

  • configure prints CUDA target architectures: 110 and resolves /usr/local/cuda/bin/nvcc (NVIDIA 13.0.88);
  • 30 *.cu.o objects, each containing exactly one cubin, all sm_110cuobjdump --list-elf over every object reads 30 sm_110. 30 of the tree's 53 .cu files is correct, not partial: fa2, cutlass-nvfp4, cutlass-nvfp4-sm100, cutlass-fp8, scaledmm-c3x-sm90, scaledmm-c3x-sm100 and fp4-mma all resolve DISABLED for [110], only marlin-nvfp4 is ENABLED, and configure says the TU set is narrowed by VT_CUDA_FEATURE_TABLE. CUTLASS is absent and supplying it changes nothing — the cells are arch-gated, not CUTLASS-gated;
  • ldd libvllm.so resolves libcudart.so.13 and libcublasLt.so.13.

Runtime, on the device: test_cuda_backend reports CUDA compute capability: sm_110 and pageable=1 integrated=1 UnifiedMemory=true, 6/6 cases and 25/25 assertions. A hand-written nvcc -arch=sm_110 kernel also launches and returns correct values.

Build was -j4 on purpose (vm.overcommit_memory=1, zero swap, no OOM killer — the box reboots instead). It cost nothing: 1460/1460 targets in ~20 min at peak ~6 GB of 122 GB.

The baseline — 14 red, and that is the deliverable

ctest -j4 --timeout 1800 at 5a0ffe9e3: 484 tests, 468 passed / 2 skipped / 14 FAILED, 177.89 s. All 14 reproduce at -j1, so none is a starvation artefact. Nothing was fixed; the full table with per-test first-failing assertions is in .agents/environment.md and in #955.

They collapse into four causes. Ten are the build honestly refusing what sm_110 lacks — five throw vt: no kernel for op QuantFp8Static (id 52), four throw built without the vendored FlashAttention-2 on MLA prefill. Two hardcode GB10: test_platform:307 asserts is_device_capability_family(120), and test_op_parity:2487 replays a dgx-captured output_cbor_sha256 inside a case that names itself dgx-only and runs anyway. test_capi's SIGSEGV and test_linear_method's un-run MXFP4 fused path are already red on GB10 (#907).

The one substantive finding is test_ops_moe_grouped:1144: NVFP4 block8-vs-block16 M=8 K=4096 N=4096 bitdiff=15/32768. marlin-nvfp4 IS enabled for [110], so unlike the other groups this is a live kernel disagreeing with itself across block sizes on hardware that runs it. Possibly adjacent to #325 (same cell, same device) but that is a throughput claim and this is a correctness one.

Two things stated plainly rather than worked around

The spec's W0.5 gate is not met. It read "the existing suite passes there", and it cannot: ten of the 14 reds are feature absence this row cannot make green. The spec now says so and replaces it with the gate that actually binds — a row regresses on Thor only if it lengthens the list of 14.

One false red was mine, briefly. test_serve_low_tools failed the first run with FileNotFoundError: 'shellcheck': tests/tools/test_online_gate_startup.py:260 shells out and raises rather than skipping when the binary is absent — an absent instrument reading as a code verdict. That was a property of my image, not of Thor. shellcheck is in the recorded Dockerfile and the test passes; the 14 above are with it installed.

Also corrected in the records

nvidia-smi on Thor was never broken — it works under sudo -n and fails only unprivileged, so NvRmMemInitNvmap failed: Permission denied was a privilege problem. Its memory columns read [N/A] because this is an integrated GPU with no VRAM counters, so read free -g instead. ~/gpu.lock exists again (the 2026-08-11 note saying it does not is stale) and a host local-ai worker is back.

Verification

scripts/agent-preflight.sh --staged is green on every record gate that applies (check-agent-record, doc-checkpoint --staged, now-current --staged, trailer and commit-style suites). The other failures it reports — check-release-binary-contract, check-release-workflow, check-test-registration and their three mutation suites — reproduce identically on a clean main and are unrelated to this diff, and test_cpu_x86_llamacpp_floor is #618 firing at loadavg 195 on the dev box.

No lifecycle state changed, so no STATUS/BENCHMARKS write is owed; the row stays SPIKE with no engine code. .agents/issue-index.md is appended at the end only.

🤖 Generated with Claude Code

…seline caught a segfault on main (#699, #955, #960)

Option B of the dots3-note spec §6.4 needs somewhere our own arm can run, and
Thor at 192.168.68.23 is the only non-GB10 CUDA box we have. It had no CUDA
toolkit, no cmake and no nvcc, and it cannot get them: `/` is a read-only 4.4 G
ext2 loop on an immutable Kairos image with 1.3 G free, so `apt install` into it
does not exist as an option. The toolchain therefore lives in a container pinned
by DIGEST — the `13.0.1` tag moves — and `/home` (362 G free) holds the checkout.

The three flags that make the GPU visible are `--runtime=nvidia`,
`-e NVIDIA_DISABLE_REQUIRE=1` and `sudo -n`. The box's own
`/home/mudler/_build_thor.sh` asserts the runtime "REFUSES this image on its
driver" and omits `--runtime` on that basis; it is wrong, and only because it
also omits the DISABLE_REQUIRE flag. With all three, `cudaGetDeviceCount`
returns 1 and an `nvcc -arch=sm_110` kernel launches and returns correct values.

Verified rather than assumed, because a build that quietly disables CUDA is the
failure mode here: configure prints `CUDA target architectures: 110`; all 30
`*.cu.o` contain exactly one cubin each and every one is `sm_110`; `libvllm.so`
links `libcudart.so.13`. 30 of 53 `.cu` files is CORRECT — `fa2`,
`cutlass-nvfp4`, `cutlass-fp8`, `scaledmm-c3x-*` and `fp4-mma` all resolve
DISABLED for `[110]` and only `marlin-nvfp4` is ENABLED, so the feature table
narrows the TU set on purpose. On the device, `test_cuda_backend` reports
`sm_110`, `integrated=1`, `UnifiedMemory=true`, 25/25.

THE BASELINE MOVED WHILE THIS PR WAS OPEN, AND THAT IS THE HEADLINE. Measured at
5a0ffe9 it was 484 tests / 14 red. Re-measured on the same box in the same
container after rebasing onto 2daa328 it is 485 tests / 15 red, and the FP8
group changed CHARACTER: `vt: no kernel for op QuantFp8Static (id 52) on device
cuda` — a loud, correct refusal — became `[vt reference-tier] ... running the
PORTABLE CPU fallback` followed by SIGSEGV. Five clean refusals became five
crashes and #842's new `test_ops_fp8_cpu` added a sixth, crashing at :279 in the
case named "G2: CPU QuantFp8Static equals CUDA QuantFp8Static byte for byte".
`cutlass-fp8` is ENABLED on GB10 and DISABLED for [110], so the native kernel
exists on the gate host, the fallback is unreachable there, and nothing in CI
could see it. Filed as #960; not fixed here, because it is someone else's kernel
row and wants its own spec.

The rest of the 15 are recorded as #955, the sm_110 counterpart of #907, and
nothing is fixed among them either — knowing which tests are red on sm_110 IS
the deliverable. Four throw `built without the vendored FlashAttention-2`, two
hardcode GB10 (`test_platform` asserts capability family 120; `test_op_parity`
replays a dgx-captured hash in a case that names itself dgx-only and runs
anyway), and `test_capi`/`test_linear_method` are already red on GB10. The one
substantive standing finding is `test_ops_moe_grouped` at bitdiff=15/32768 on a
Marlin NVFP4 cell that IS enabled for [110] — a live kernel disagreeing with
itself across block sizes, not an absent feature.

So the spec's W0.5 gate as written — "the existing suite passes there" — is not
met and was the wrong gate: it would either block every brick forever or invite
someone to weaken a test. The spec now carries the replacement and the reasoning
for it, so a future agent reads it there rather than in a PR body: a row
regresses on Thor only if it lengthens the list. And because the list is not
constant, the spec also says to re-measure whenever the base moves across
`src/`, `tests/` or `CMakeLists.txt`.

One trap cost a false red. `test_serve_low_tools` failed the first run with
`FileNotFoundError: 'shellcheck'` — `tests/tools/test_online_gate_startup.py:260`
shells out and raises instead of skipping when the binary is absent, an absent
instrument reading as a code verdict. `shellcheck` is in the recorded Dockerfile
so it passes here, and the record says plainly that this HIDES the harness
defect rather than fixing it.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
@localai-bot
localai-bot force-pushed the row/dots3-note-w0.5-thor branch from ba4ed0c to b1ae135 Compare August 15, 2026 21:10
@localai-bot

Copy link
Copy Markdown
Collaborator Author

Rebased onto 2daa3287f (PR #934) and re-measured. New head b1ae13538.

The rebase pulled 37 files across src/, tests/ and CMakeLists.txt (+4093/-118) into the tree the baseline measured, including src/vt/cuda/cuda_matmul_fp8_cutlass.cu and a new tests/vt/test_ops_fp8_cpu.cpp, so the baseline was re-run rather than carried over. It moved, and the PR is retitled because of what it found.

5a0ffe9e3 2daa3287f
total 484 485
failed 14 15
FP8 group Failed — clean throw vt: no kernel for op QuantFp8Static (id 52) on device cuda SEGFAULT

The FP8 group did not just get worse, it changed character: the loud refusal became [vt reference-tier] op=QuantFp8Static device=cuda has NO native kernel; running the PORTABLE CPU fallback (correct but slow) followed by SIGSEGV. Five clean refusals became five crashes, and #842's new test_ops_fp8_cpu adds a sixth, crashing at :279 in the case named "G2: CPU QuantFp8Static equals CUDA QuantFp8Static byte for byte" — the test name states the mechanism. cutlass-fp8 is ENABLED on GB10 and DISABLED for [110], so on the gate host the native kernel exists, the fallback is unreachable, and no CI lane could see it.

Filed as #960, not fixed here. Attribution to f270b4b0a (#842) is indicated by the diff and by the reference-tier log line; it is not bisected, and the issue says so.

Records updated to the new base throughout: environment.md's table (new test numbers 382/385/390/415/416/418/433), the ## Now and §7 W0.5 entries in the spec, and two issue-index.md rows appended at the end (#955 restated at the new SHA, #960 added). .agents/issue-index.md diffs as exactly +2 lines against origin/main with nothing removed.

Spec reconciled by section, not by conflict marker. .agents/specs/dots3-note.md was taken from origin/main wholesale and my three scoped edits reapplied on top, so §6.4's option-B decision, the new ## Owed section and 934's framing survive untouched. ## Now is rewritten so there is ONE account of the state: it reports W0.5 landed, points at the environment.md recipe rather than restating the Thor facts, and names W1 as next. One further staleness left by #934 is fixed in passing — §7's lead-in still read "Nothing past it is dispatched until §6.4 is answered", which is no longer true.

The differential gate reasoning now lives in the spec, not only here (§7's W0.5 entry): all-green is the wrong bar on a host whose arch legitimately lacks features, because it would either block every brick forever or invite someone to weaken a test; a row regresses on Thor only if it lengthens the list. The spec also now says to re-measure whenever the base moves across src/, tests/ or CMakeLists.txt — this rebase is the evidence for why.

scripts/agent-preflight.sh --staged reports All gates green at the new head; the release and test-registration gates that were red at the previous base are green on current main. Still not merged.

@localai-bot localai-bot changed the title docs(MODEL-MM-dots3-note): W0.5 — Thor is a CUDA host now, and its baseline is 14 red (#699, #955) docs(MODEL-MM-dots3-note): W0.5 — Thor is a CUDA host now, and its baseline caught a segfault on main (#699, #955, #960) Aug 15, 2026
localai-bot pushed a commit that referenced this pull request Aug 16, 2026
…W6's own variable shadow (#965, #672)

`windows-msvc-cpu` and `windows-msvc-vulkan` fail on every open pull request:

  server_main.cpp(1315,55): error C2220: the following warning is treated as an error
  server_main.cpp(1315,55): warning C4456: declaration of 'loaded' hides
                            previous local declaration

That is W6's own speech-attach block declaring `loaded` inside the scope of the
text engine's `loaded` at `:1025`. It is the ONLY warning in the job, it has
been on `main` since W6 landed, and it is fixed here by renaming the inner
declaration. Nothing is suppressed and no detector is weakened.

WHAT FOUND IT WAS THE MATCHED-ARM CHECK, NOT THE LABEL, and that is the part
worth recording. Both jobs are habitually red and habitually attributed to #645
— which is the `M_PI` portability regression in three LTX2 sources: different
file, different detector, different failure. A second cause sitting behind a
known-red name is invisible for exactly as long as nobody reads the log.

Three unrelated open pull requests that touch no speech surface — #956, #950 and
#939 — fail with the identical C4456, which is what separates "pre-existing"
from "mine". `main` carries no baseline because `windows-msvc-*` are PR-only
(#584), so the failure presents to each author in turn as a red their own diff
caused.

Verified after the rename: 7 of 7 server ctest cases pass, `test_openai_api_server`
is 62 cases / 733 assertions, and `vllm-server --speech-model <dir>` with no
`--model` starts and serves for real:

  server: speech/music-only model (family=minimax-music3, 44100 Hz,
          text-only synthesis, family DETECTED); serving /v1/audio/speech
  server: listening on http://0.0.0.0:18923 (model 'minimax-music3')

Issue: #965

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
localai-bot pushed a commit that referenced this pull request Aug 16, 2026
…the first, and it came from main (#968, #672)

With #965's `C4456 'loaded' shadow` removed, `windows-msvc-cpu` and
`windows-msvc-vulkan` failed again on this row's pull request — and on a
different cause:

  include\vector(1461,29): error C2220: the following warning is treated as an error
  include\vector(1461,29): warning C4244: '=': conversion from 'const double'
                           to 'float', possible loss of data

raised from `src/vllm/multimodal/ltx2_video.cpp:203,214`, the two narrowing
`positions.assign` calls that `c7cb59fbb` (#964, LTX25-TOKEN-APPEND) landed on
`main` while this row was in flight. `StreamState::positions` and
`Ltx2LatentState::positions` differ in element type; GCC and Clang narrow
silently, MSVC diagnoses and the build treats it as an error.

NOT FIXED HERE, deliberately. #964's own comment at `ltx2_video.cpp:129-132`
reasons that "double -> float -> double reproduces the bits", so the narrowing
is intentional and a silencing `static_cast` would be a claim about that
reasoning rather than a formatting repair. It belongs to the lane that owns the
round trip. Filed as #968 with the evidence rather than papered over.

THE MATCHED ARM SPLITS EXACTLY ON THE MERGE BASE, which is what makes it
inherited rather than mine. Grepping each `windows-msvc-cpu` job log for the
warning: #966 and #951, both on `c7cb59fbb`, hit it twice each; #967, #956,
#950, #939 and #938, all based before it, do not hit it at all. This row's diff
touches zero LTX2 files.

THE FINDING WORTH CARRYING is not either warning. It is that TWO INDEPENDENT
CAUSES WERE STACKED BEHIND ONE HABITUALLY-RED JOB NAME, and the first hid the
second — and that neither was #645, the `M_PI` regression both jobs are usually
attributed to. A known-red list tells you a job is often red. It never tells you
that today's red is the same one. Only reading the log does.

Issue: #968

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]
localai-bot added a commit that referenced this pull request Aug 16, 2026
… heard, and the five keys upstream refuses that we dropped (#672, #953, #965) (#966)

feat(MODEL-MUSIC-MUSIC3): a music-only server, an example that can be
heard, and the five keys upstream refuses that we dropped (#672, #953)

Developer directive: parity on what upstream supports — "we want to be a
good
reference" — usage docs for MiniMax-Music3, and in those docs the
weights. Then,
mid-flight: "we should allow to load only the music model" and "we need
to have
an e2e test working".

FOLLOWING_AGENTS_PROTOCOL

## The upstream surface, enumerated rather than summarized

SGLang-Omni `748a0b43` `models/minimax_music3/` and diffusers `c6da9936`
`modular_pipelines/minimax_music3/`, read field by field and recorded
with
`file:line` in spec §10.1 so the next reader re-derives nothing.

**Closed here:** the music-only server, the missing example, and five
refusals.
**Owed and named:** the non-`wav` response formats, request batching and
`/v1/audio/speech/batch`, the 32 kHz delivery resample.
**Permanently refused rather than owed:** streaming — neither upstream
arm has
it (`supports_streaming_vocoder=False`).
**One place we are ahead of both arms:** `guidance_scale` is a real
per-request
control here, where diffusers freezes it at 1.7 into the guider
component
(`denoise.py:180`) and SGLang exposes it only as a serve-time knob.

## `--model` is optional when `--speech-model` is given

Serving a 28.5 GB music model also forced loading an unrelated text
model, and
on this box the smallest text checkpoint is 35B — so the recipe this
project
documented was effectively unrunnable. Upstream's own is `sgl-omni serve
--model
MiniMaxAI/MiniMax-Music3`, no text tower anywhere.

    vllm-server --speech-model /path/to/minimax-music3

Third instance of a shape already in `server_main.cpp`: a pooling
checkpoint
serves `/v1/embeddings` alone, a Parakeet checkpoint serves
`/v1/audio/transcriptions` alone. It mirrors vLLM's task-conditional
registration (`api_server.py:255-265`).

**Additive, and proved rather than argued.** The only case whose verdict
changes
is BOTH flags absent, which was an error and remains one with a message
naming
both options. The route table is gated in both directions over a real
socket,
because a handler-dispatch test cannot see route registration at all.

## The example the music family did not have

`examples/minimax_music3_gen` — a thin client of `include/vllm.h` and
nothing
else, like `parakeet-transcribe` and `vllm-cli`. Hearing this model
previously
needed a running server plus a `curl`, or a C ABI caller nobody had
written.

## Five keys upstream refuses by name were SILENT here (#953)

`temperature`, `top_p`, `top_k`, `repetition_penalty` — refused upstream
at
`request_builders.py:14-19,109-114`, because this model's autoregressive
stage
has ONE sampler, a fixed top-50 draw (`encoders.py:48,94-103`). And
`max_new_tokens`, upstream's LENGTH spelling in 25 Hz frames rather than
seconds
(`request_builders.py:56-68`), so a 250-frame request silently became
the
family's 60 s default. That is the #925 class exactly, in the same file
that
already carries #925's refusal one paragraph above. Fixed in flow.

## The e2e gate no longer reports a skip wearing a pass

It read 5 cases / 5 passed with **`assertions: 0`** whenever the
checkpoint was
absent — the same shape that fooled this project on
`test_qwen3_paged_engine`.
Split into a checkpoint-free half that runs unconditionally in CI
(request
contract, both ceilings, the speech-only route table over a real socket
with a
stub synthesizer) and the env-gated half, whose HTTP case now drives the
real
engine over a real socket against the music-only server shape. A
coverage-report
case prints which arms ran, every run.

The full arm was run: `POST /v1/audio/speech -> 200 audio/wav, 12332
bytes in
518 s wall`, 2 AR frames -> 6 latent frames -> 3072 samples/channel,
6144 int16
samples all non-zero, 0 clipped, 2818 of 3072 positions differing
between L and
R, and `/v1/completions` + `/v1/chat/completions` both 404 from the
route table.
`checkpoint_arms_run=5`.

| arm | cases | assertions |
|---|---|---|
| `test_minimax_music3_e2e_real`, no env vars | 9 | 37 (was 5 / **0**) |
| `test_minimax_music3_e2e_real`, checkpoint only | 9 | 86 |
| `test_minimax_music3_e2e_real`, checkpoint + `VLLM_CPP_MUSIC3_DIT=1` |
9 | **582** |
| `test_speech_api` | 6 | 67 |
| `test_openai_api_server` | 62 | 733 |
| `test_openai_conformance` | 23 | 252 |
| `test_minimax_h3` (unchanged) | 79 | 57395 |
| server flag ctest cases | 7 passed | |

## The weights are documented (porting-a-model.md §2.1)

`docs/USAGE.md` gains component-by-component tables: the diffusers arm
at
`MiniMaxAI/MiniMax-Music3`@`fbdf52fbaaca799592917417eb05f1899f1255ec`,
**28.5 GB
resident** (28 517 617 303 B, measured) out of a 57.4 GB repository and
why they
differ; the native `.pth` arm we refuse and SGLang-Omni serves; the one
implemented GGUF Q4_K artifact with its sha256; and the fourteen
third-party
quantized repositories in five formats, each marked refused. The
revision is
verified rather than copied —
`condition_encoder/diffusion_pytorch_model.safetensors`
on disk hashes to that revision's own LFS record.

## A sample a human can hear

2.0 s of 44100 Hz stereo from this engine in 3286 s of wall clock: RMS
0.03169,
peak 0.97437 with 0 clipped samples, 84 073 of 88 064 positions
differing
between left and right. **Its samples are compared to nothing** — §5
withdrew
the token gate — so it shows the pipeline runs, not that the music is
right. It
is not committed: `check-pr-size.py` classifies every path and none
takes a
`.wav` outside `tests/`, where a file compared to nothing would sit
beside the
goldens and imply it was one.

## The four asks, answered directly

**1. Music-only server.** `vllm-server --speech-model <dir>` with NO
`--model`
starts and serves, observed live rather than inferred:

    server: speech/music-only model (family=minimax-music3, 44100 Hz,
text-only synthesis, family DETECTED); serving /v1/audio/speech
    server: listening on http://0.0.0.0:18923 (model 'minimax-music3')

`--model` alone and `--model` + `--speech-model` are **byte-identical in
behaviour**. The whole change is one new early branch, `if
(args.model_dir.empty())`,
which loads the speech engine and `return 0`s before reaching a single
line of
the existing path; nothing downstream of it was touched. The only case
whose
verdict changes is BOTH flags absent, which was an error and remains
one.
Server suites: **7 of 7** ctest cases (4 pre-existing + 3 new — neither
flag is
still an error and now names both options; `--speech-model` alone
reaches the
speech LOAD; `--speech-family` alone still demands a checkpoint),
`test_openai_api_server` **62 cases / 733 assertions** (+1 case / +24
assertions,
the speech-only route table over a real socket),
`test_openai_conformance`
**23 / 252** unchanged.

**2. e2e, three arms.** What a bare CI run executes unconditionally: the
request
contract on the exact body the real case posts, the near-miss and
sampling
refusals, the duration arithmetic including both ceilings, and the
speech-only
route table over a real socket with a stub synthesizer. What stays
env-gated:
everything needing the 28.5 GB checkpoint, plus the two 2.4B-DiT arms
behind
`VLLM_CPP_MUSIC3_DIT`.

| arm | cases | assertions | checkpoint arms run |
|---|---|---|---|
| no env vars (what CI runs) | 9 | **37** | 0 — was 5 cases / **0
assertions** |
| `VLLM_CPP_MUSIC3_CHECKPOINT` | 9 | **86** | 3 |
| + `VLLM_CPP_MUSIC3_DIT=1` | 9 | **582** | 5 |

**3. The five keys.** All five were **accepted and silently dropped**;
all five
are **now refused by name**.

| key | upstream anchor | why it cannot be honoured |
|---|---|---|
| `temperature` | `request_builders.py:14-19,109-114` | the AR stage's
only sampler is a fixed top-50 draw, `encoders.py:48,94-103` |
| `top_p` | same | no nucleus branch exists |
| `top_k` | same | `_AR_SAMPLING_TOP_K` is a module constant of 50 |
| `repetition_penalty` | same | no penalty is applied anywhere in the
loop |
| `max_new_tokens` | `request_builders.py:56-68`, `constants.py:4-5` |
upstream's LENGTH, in 25 Hz frames not seconds; the refusal names
`audio_duration` and the /25 conversion |

**4. The weights table** (`docs/USAGE.md`, "MiniMax-Music3: the exact
weights").
It carries: repo **and** revision —
`MiniMaxAI/MiniMax-Music3`@`fbdf52fbaaca799592917417eb05f1899f1255ec`,
verified
rather than copied, since
`condition_encoder/diffusion_pytorch_model.safetensors`
on disk hashes to `83179c5e…a202c2a4d`, that revision's own LFS record;
the
Q4_K artifact's sha256 `4c5d41b2…c70cbdd0` at revision `c36aaeed…` with
its exact
byte count; **28.5 GB resident (28 517 617 303 B, measured) versus 57.4
GB
repository**, with the reason they differ; the refused native `.pth` arm
(`qwen_7B/`, `flowmatching_vae.pth`, `dav.pth`) and that SGLang-Omni
serves it;
and all fourteen community quant repositories across five formats, each
marked
refused and each marked **third-party** rather than first-party. This is
the
first application of `.agents/porting-a-model.md` §2.1 (landing as
#951).

## Two reds stacked behind one habitually-red job name

`windows-msvc-cpu`/`windows-msvc-vulkan` are usually attributed to #645
(`M_PI`
in three LTX2 sources). **Neither of the two causes here was #645**, and
the
first hid the second.

**#965, fixed in flow.** `C4456: declaration of 'loaded' hides previous
local
declaration` at `server_main.cpp:1315` — W6's own speech-attach block
declaring
`loaded` inside the text engine's `loaded`. The only warning in the job,
on
`main` since W6 landed. Matched arm: #956, #950 and #939, none touching
the
speech surface, fail identically. Renamed; nothing suppressed.

**#968, filed and NOT fixed here.** With the shadow gone the same jobs
failed
again on `C4244: conversion from 'const double' to 'float'`, raised
inside
MSVC's `<vector>` from `ltx2_video.cpp:203,214` — two narrowing
`positions.assign` calls that `c7cb59fbb` (#964) landed on `main` while
this row
was in flight. **This branch touches zero LTX2 files.** The matched arm
splits
exactly on the merge base: #966 and #951 (on `c7cb59fbb`) hit it,
#967/#956/
#950/#939/#938 (before it) do not. It is deliberately left to the
LTX-2.5 lane —
#964's own comment reasons that "double -> float -> double reproduces
the bits",
so a silencing cast is a claim about that reasoning rather than a
formatting fix.

**The finding, which outlives both:** a known-red list tells you a job
is often
red. It never tells you that today's red is the same one. Only reading
the log
does — and here it took two readings, because removing the first cause
is what
made the second visible.

<!-- kept for the record -->
### The first of the two, in detail (#965)

`windows-msvc-cpu`/`windows-msvc-vulkan` failed here, and they are
**not** #645
(`M_PI` in three LTX2 sources). They were W6's own
`C4456: declaration of 'loaded' hides previous local declaration` at
`server_main.cpp:1315` — the only warning in the job, on `main` since W6
landed.
The matched-arm check is what separated it from my diff: #956, #950 and
#939, all
touching no speech surface, fail identically. `main` has no baseline
because
`windows-msvc-*` are PR-only (#584), so it presents to each author in
turn as
their own red. Filed and fixed in flow by renaming the inner
declaration; nothing
suppressed.

## Mutations

Four run, four fire: sampling refusal neutered (5 assertions red),
`max_new_tokens` refusal neutered (2 red), `--model` made mandatory
again
(2 ctest cases red), generate routes registered unconditionally (3 cases
/
6 assertions red in the api-server suite, 1 / 2 in the e2e suite).
Sources
restored and verified sha256-identical.

Supersedes #954 (untrailered merge commits) and #963 (a
`server_main.cpp` commit
that owed `docs/USAGE.md` under the per-commit documentation
checkpoint). Same
tree, linear history, every commit green on `check-doc-checkpoint`,
`check-commit-trailers` and `check-commit-style` locally before pushing.
Every
source file is byte-identical to the one built and gated.

Issue: #672

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:claude-opus-5 [Claude Code]

---------

Co-authored-by: Ettore Di Giacinto <mudler@localai.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants