Repository navigation
Conversation
Unsloth's UD-IQ1_S keeps the routed gate/up experts in IQ1_S (1.5625 bpw, 50 B per 256-value block), a format no backend could run: the dequantizer, the MMVQ dot and the grouped expert kernels now cover it on the GPU (Fmt<19>, Split<19>, dq_iq1_s, vec_dot_iq1_s_q8_1), and the AVX-2 multi-token kernels cover IQ1_S and IQ1_M on AVX2 CPUs. gguf_reader knows the block geometry, and the fixture/parity suites (iq_parity, iq_multi_parity, native_grouped_parity) cover the new type. Validated on a Radeon PRO W7800 (gfx1100, ROCm 7.13): iq_parity dequant 0.00e+00 against gguf-py; the MMVQ and grouped kernels bitwise equal to the per-column and v1 kernels; native_expert_parity vs ggml 3.1e-08 (IQ1_S) / 4.1e-08 (IQ1_M). Also adds the gfx1100 hipBLASLt 1.3.0 tuning table (3.6-18.2x vs plain hipBLASEx over the engine's 30 shapes, calibrated on a W7800) and names the Radeon PRO W7900 / W7800 in the docs.
iq512_supported() did not list IQ1_S (19) or IQ1_M (29), and native_expert.cpp only takes the AVX-2 kernel when the CPU has no AVX-512, so an AVX-512 CPU (Ice Lake+, Zen 4/5) ran these two formats through ggml-cpu's single-token vec_dot - slower than the AVX-2 kernel an older CPU gets. Port the AVX-2 row_dot_iq1s/row_dot_iq1m to 512-bit lanes (64 values per pass, the same grid decode and qh delta as ggml's ggml_vec_dot_iq1_s_q8_K / _iq1_m_q8_K; only the float-addition order differs), routed through row_dot_any. AVX-512 has no EVEX vpsignb, so the grid sign is applied with vpabsb + a masked subtract under the sign bits. Validated with Intel SDE (sde -spr): native_expert_parity synthetic iq1_s and iq1_m, rel 1.0e-07 against ggml-cpu's vec_dot, width-invariant over 1..3 tokens, 0 failures.
The share of the VRAM misses the GPU reads over PCIe (`--pcie-frac`) was set from a host->device link probe alone, capped at 0.55. But the best share also depends on the CPU and the GPU, and it runs both ways: on a Ryzen 7 3800X + Radeon PRO W7800 (x16, 28 GB/s) the GPU taking every miss measured 39-40 tok/s against the probed 0.55's 26, while in the RDNA2 x8 bench `--pcie-frac 0` beat the probed 0.39. A `--serve` now sweeps a few shares over its first verify windows - the probed one first, then 0 and 1.0 - and keeps the one with the lowest (CPU pool + GPU wait) per routed expert entry (normalized so a window that accepted more drafts is comparable; the min of a point's windows rejects a one-off spike). The winner holds for the rest of the process, so only the first request pays. `--pcie-frac <value>` pins a share and skips the sweep; `--pcie-frac auto` does the same for a CLI run. Measured (600-token prompt, MTP, UD-IQ1_S on the W7800): serve 40.2 tok/s on the first request and 75.3 on the second (persisted), against 26.5 at the probed 0.55. iq_parity / iq_multi_parity / native_expert_parity / native_grouped_parity: 0 failures.
…the GPU and on AVX-2, and IQ1_S / IQ1_M on 512-bit lanes kernels: run IQ1_S (GGML type 19) on the GPU and on AVX-2 Unsloth's UD-IQ1_S keeps the routed gate/up experts in IQ1_S (1.5625 bpw, 50 B per 256-value block), a format no backend could run: the dequantizer, the MMVQ dot and the grouped expert kernels now cover it on the GPU (Fmt<19>, Split<19>, dq_iq1_s, vec_dot_iq1_s_q8_1), and the AVX-2 multi-token kernels cover IQ1_S and IQ1_M on AVX2 CPUs. gguf_reader knows the block geometry, and the fixture/parity suites (iq_parity, iq_multi_parity, native_grouped_parity) cover the new type. Validated on a Radeon PRO W7800 (gfx1100, ROCm 7.13): iq_parity dequant 0.00e+00 against gguf-py; the MMVQ and grouped kernels bitwise equal to the per-column and v1 kernels; native_expert_parity vs ggml 3.1e-08 (IQ1_S) / 4.1e-08 (IQ1_M). Also adds the gfx1100 hipBLASLt 1.3.0 tuning table (3.6-18.2x vs plain hipBLASEx over the engine's 30 shapes, calibrated on a W7800) and names the Radeon PRO W7900 / W7800 in the docs. kernels: run IQ1_S and IQ1_M on 512-bit lanes iq512_supported() did not list IQ1_S (19) or IQ1_M (29), and native_expert.cpp only takes the AVX-2 kernel when the CPU has no AVX-512, so an AVX-512 CPU (Ice Lake+, Zen 4/5) ran these two formats through ggml-cpu's single-token vec_dot - slower than the AVX-2 kernel an older CPU gets. Port the AVX-2 row_dot_iq1s/row_dot_iq1m to 512-bit lanes (64 values per pass, the same grid decode and qh delta as ggml's ggml_vec_dot_iq1_s_q8_K / _iq1_m_q8_K; only the float-addition order differs), routed through row_dot_any. AVX-512 has no EVEX vpsignb, so the grid sign is applied with vpabsb + a masked subtract under the sign bits. Validated with Intel SDE (sde -spr): native_expert_parity synthetic iq1_s and iq1_m, rel 1.0e-07 against ggml-cpu's vec_dot, width-invariant over 1..3 tokens, 0 failures. (The PR's third commit, the PCIe share measured over a --serve's first windows, is not taken: StrataPool's calibrated configs pin --pcie-frac, and a pool worker's windows are not timed that way.) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0157fjixQD2nRxvCvtXq66DD
IQ1_S was missing from both _strata_mmq_types and mmq::supported(), and from the dispatch switch, so Unsloth UD-IQ1_S packs fell off the MMQ prompt path entirely: every expert ran the per-expert dequant-to-FP16 fallback (the RTX 5070/IQ3_S reference uses MMQ). Add it; the iq1_s MMQ instance already exists in the pinned ggml and force_float_ref is NULL, so a synthetic run feeds random valid blocks (the check decodes them through ggml's to_float). Measured on a Radeon PRO W7800 (ROCm 7.13, 600-token prompt, same build): MMQ off 169.7 tok/s MMQ on, IQ1_S uncovered 196.4 tok/s (+16%, the other formats) MMQ on, IQ1_S covered 326.8 tok/s (+66% from IQ1_S alone) hip_prefill_mmq_parity extended with a synthetic-IQ1_S-GU case: rel_l2 0.0038 (screen limit 0.04), max_abs/ref_rms 0.0145, 0 zero rows.
Resolve the moved iq256_supported / iq512_supported functions (now in native_expert.cpp on main): take main's deletion in iq_avx2.cpp and iq_avx512.cpp, and port this branch's added types (IQ1_S=19, 29) into native_expert.cpp.
|
Merged The conflict: Resolution: take
Validated (ROCM 7.13, gfx1100, pinned ggml
No other conflicts; the branch now sits on current |
- generate.cpp: main's PcieAuto and the branch's `--pcie-frac auto` sweep both measure the share, so both stay, one driver at a time: an explicit `--pcie-frac auto` picks the sweep (and counts as a given share), PcieAuto otherwise when it is armed. - iq_avx2.cpp / iq_avx512.cpp / native_expert.cpp: no new conflict; the earlier resolution (the predicates moved to native_expert.cpp, with IQ1_S 19 and IQ1_M 29) carried over.
|
Merged main (0.1.42) again; the branch is clean against it.
Built the merged tree ( |
|
Thanks. The PR bundles three things: IQ1_S support, IQ1_S on the MMQ prefill path and a measured PCIe share that changes the default. We cannot validate IQ1_S here (no UD-IQ1_S pack and no gfx1100 card), and the PCIe part overlaps the share refinement already in the engine, so we are not taking it as a speed change. A PR with only the IQ1_S format support (kernels + reader + parity tests), rebased on the current main, is something we could review separately. |
# Conflicts: # setup.py # src/program/generate.cpp
|
Thanks for the pull request. We're resetting the tracker for 0.2.0-beta. There are more than 1,300 open issues and pull requests, too many for us to review properly, so we're closing everything that isn't being worked on right now. Closed here does not mean rejected. To reopen it takes about two minutes:
The rules are in CONTRIBUTING.md. |
…ne 0.1.49.1) into pool-support Conflicts: src/kernels/cpu/iq_avx2_rows.inl - upstream's own AVX2 IQ1_M rows (ggml's float order, pair sums once per call, the wide prompt form) replace Niko1221#1374's IQ1_M; Niko1221#1374's IQ1_S (19) rows are kept beside them (non-exact dispatch only; upstream has no IQ1_S), and iq256/iq512_supported still send Qwen's IQ1_S/IQ1_M experts to these rows. CMakeLists.txt (0.1.49.1 after our pre-project MSVC flags), README.md (ours). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0157fjixQD2nRxvCvtXq66DD
…bles; the raw results and the chart removed The 2026-10-06 results (bench/results/2026-10-06-stratapool, 27 files) and docs/media/pool-results.svg described StrataPool on Strata 0.1.40.1. The README now gives the expected gains as ranges against the faster PC alone (one chat +20-30%, two chats +25-30%, long prompts about a third slower, Several chats a loss on two PCs), says what they were measured on, adds the long-session numbers from StrataPool on Strata 0.1.45 and the VRAM headroom lesson, and points at tools/pool_bench.py for measuring a pool (its output folder, bench-results/, is already ignored). Also: the "CPU help on short prompts" line and architectds' CPU-assist credit row are gone (Strata's own CPU prefill share replaced it at 0.1.43, as the credits paragraph says), Niko1221#1374's row notes Strata 0.1.49's own AVX2 IQ1_M rows, and DeepSeek-V4.1 is named as Share-requests-only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0157fjixQD2nRxvCvtXq66DD
…ool-support Conflicts (14 files): - generate.cpp (12): upstream took Niko1221#1284 (--adapt-decay checked); STRATA_PIPED_MTP (Niko1221#4121) beside the pool's batch-MTP rules (pmtp needs a local split, so never on a pool coordinator, whose last stage may be a worker: st_out/st_launch keep the remote stage, pmtp_verdict / batch_launch_rows only where pmtp is on), the pool worker's draft-in-groups refusal kept, the pool's 96 MiB beside nibble_max_slot_bytes, wide pool rows beside batch_max_t(), the invariant window pool function with pool_pipe, pool_conv_retain closed before ParkSource, the slot penalty windows in the non-pmtp group fill, the pool's batch-wait line and the local-stage profile loop. - prefill.cpp: layer-major prefill (Niko1221#3976) declines on a pool coordinator or worker (remote_next / headless): its walk has no hand-off to other PCs yet. - iq_avx512.cpp: upstream's Singleton rows beside Niko1221#1374's IQ1_S / IQ1_M 512-bit rows (row_dot_any forwards it); iq_kernels.cu: IQ1_S (19) beside the new TQP types 147-149. - conversation_cache.hpp: pool_id beside dev_tag / pending; expert_cache.*: upstream's Niko1221#1911 and nibble code. - serve/server.py: split serving (Niko1221#4000) in the plain (role off) branch beside the pool roles; #pool kept on the URL. - serve/lifeline.py, strata_control/procs.py: upstream's own fix of the watcher token (start time only, /proc first) replaces ours. index.html: the Pool tab beside the i18n tabs. .gitignore both; CMakeLists 0.1.52; README ours. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0157fjixQD2nRxvCvtXq66DD
Round 2: IQ1_S made first-class across the pipeline, plus a PM-driven PCIe share.
What
dq_iq1_s,vec_dot_iq1_s_q8_1,Fmt<19>,Split<19>, the grouped kernels, the reader geometry, and the AVX-2row_dot_iq1s/row_dot_iq1m.iq512_supportedlisted neither, andnative_expert.cpponly takes the AVX-2 kernel off an AVX-512 CPU, so AVX-512 CPUs ran both through ggml-cpu single-token — slower than an AVX-2 CPU. No EVEXvpsignb, so the grid sign isvpabsb+ a masked subtract._strata_mmq_types,mmq::supported()and the dispatch switch, so UD-IQ1_S prefill fell back to per-expert dequant→FP16. Added; themmq-instance-iq1_s.cualready exists in the pinned ggml.--pcie-fracwas the link probe alone (capped 0.55); the best share also depends on the CPU/GPU and runs both ways. A--servesweeps the probed share, 0 and 1.0 over its first verify windows, keeps the lowest (CPU pool + GPU wait) per routed expert entry, and holds it.--pcie-frac <value>pins;--pcie-frac autofor the CLI.Measured
Radeon PRO W7800 (gfx1100, ROCm 7.13), Ryzen 7 3800X, 30 GiB RAM; UD-IQ1_S (67.5 GiB); 600-token prompt, MTP.
The share runs both ways, which is why it is measured: here the GPU taking every miss is fastest, while in the RDNA2 x8 bench
--pcie-frac 0beat the probed 0.39.Validation
strata;iq_parity(IQ1_S/IQ1_M dequant rel 0.00e+00),iq_multi_parity,native_expert_parity(IQ1_S 3.1e-08, IQ1_M 4.1e-08 vs ggml-cpu),native_grouped_parity— 0 failures.-spr(this Zen 2 cannot run it): rel ~1e-07 vs ggml-cpu, width-invariant, 0 failures.hip_prefill_mmq_parityextended with a synthetic IQ1_S case: rel_l2 0.0038 (limit 0.04), max_abs/ref_rms 0.0145, 0 zero rows.