Integrate guarded FC2 cuBLASLt schedule

This commit is contained in:
Daniel Maddern 2026-08-26 00:48:44 +07:00
parent 0298ccd1cb
commit a29b8960b0
21 changed files with 8879 additions and 60 deletions

View file

@ -160,7 +160,8 @@ video and audio tensors. Spark enables the path with
`SAGE2_BLACKWELL_DESIGN.md`, and
`benchmarks/gb10-post-optimization-profile-summary.json`.
The isolated FC2 cuBLASLt scheduling study is complete. The production
The FC2 cuBLASLt scheduling study and guarded canonical-shape integration are
complete. The production
heuristic's `_stream_k` kernel requests the same `25.664 GB` of operands as the
retained public split-K-1 schedule, but its L2 hit rate is only `53.32%` versus
`91.10%`; it incurs `9.853 GB` more L2 read misses and spends heavily in
@ -168,8 +169,15 @@ synchronization polling. Algorithm 70, tile 20, stages 37, split-K 1 is
byte-exact with zero workspace. It improves complete blocks 0, 24, and 49 by
`8.16-8.88%`, the two-step trajectory by `7.50%`, and the canonical 12-step
trajectory from `278.201 s` to `255.371 s` (`8.21%`) with exact video and audio
latents. This remains a research-retained integration candidate: production
dispatch and configuration are unchanged. See
latents. The final hardened production method improves 20-round blocks by
`7.86-9.36%` and the canonical 12-step trajectory from `286.431 s` to
`262.979 s` (`8.19%`), with 600 successful dispatches, zero fallback, and exact
latents. `H3_NVFP4_FC2_LT_SPLITK1=1` enables only the validated `M=37,810`
descriptor; nearby row counts can differ by two BF16 elements and therefore
retain the existing Comfy fallback. The extension and measured runtime ABI are
prepared during H3 model loading rather than on the first canonical request.
The Spark hot service is intentionally
stopped until performance work is complete. See
`research/fc2_nvfp4_scheduling/RESULTS.md`.
The Spark hot runtime was rebuilt and recreated with image

View file

@ -33,7 +33,7 @@ RUN python -m pip install --no-cache-dir --no-deps -e . \
ENV TORCH_EXTENSIONS_DIR=/opt/h3-blackwell-runtime/.torch_extensions
RUN TORCH_CUDA_ARCH_LIST=12.1 python -c \
"from h3_blackwell_runtime.nvfp4_quant import _vortex_scale_extension; print(_vortex_scale_extension().__file__)"
"from h3_blackwell_runtime.nvfp4_quant import _vortex_scale_extension; from h3_blackwell_runtime.fc2_lt import _fc2_lt_extension; print(_vortex_scale_extension().__file__, _fc2_lt_extension().__file__)"
ENV H3_MODEL_PATH=/models/minimax_h3_ref2va_pruned_nvfp4.safetensors
ENV PYTHONPATH=/opt/ComfyUI-sol-attn

View file

@ -394,12 +394,18 @@ tensor-pipe activity from `25.01%` to `82.42%`. There is no material global
partial-accumulator or output-reduction traffic; the baseline instead spends
heavily in Stream-K synchronization polling and loses traversal locality.
The candidate is byte-exact and improves FC2 p50 from `52.521 ms` to
The candidate is byte-exact and improves FC2 p50 from `53.618 ms` to
`15.636 ms`. Complete blocks 0, 24, and 49 improve by `8.16-8.88%`; two-step
and canonical 12-step trajectories improve by `7.50%` and `8.21%`, with exact
video and audio latents. The custom persistent-kernel branch is therefore
closed. Production integration remains separate work, so current dispatch is
unchanged. See `research/fc2_nvfp4_scheduling/RESULTS.md` and
closed. Guarded production integration is complete behind
`H3_NVFP4_FC2_LT_SPLITK1=1`. Its direct 20-round block gate improves blocks
0/24/49 by `9.36%`, `8.16%`, and `7.86%`; the exact canonical 12-step gate
improves by `8.19%`
with 600 successful dispatches and zero fallback. Shape testing found two-BF16
differences at several nearby row counts, so only `M=37,810` is eligible and
all variable shapes retain Comfy. The hot service remains stopped until the
performance program is complete. See `research/fc2_nvfp4_scheduling/RESULTS.md` and
`benchmarks/gb10-fc2-nvfp4-library-sweep-20260825.json`.
The follow-up real block-24 Sage2 decomposition now selects the next exact

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -20,6 +20,7 @@ services:
H3_FUSED_ELEMENTWISE: "1"
H3_NVFP4_MODULATE_FUSION: "1"
H3_NVFP4_SWIGLU_FUSION: "1"
H3_NVFP4_FC2_LT_SPLITK1: "1"
H3_SAGE_QKV_LAYOUT: "strided_nhd"
H3_SOL_QKV_LAYOUT: "native"
command: ["python", "/opt/h3-blackwell-runtime/tools/serve_hot_runtime.py", "--host", "0.0.0.0", "--port", "8000", "--attention", "sage2", "--warmup"]

View file

@ -37,6 +37,7 @@ services:
H3_FUSED_ELEMENTWISE: "1"
H3_NVFP4_MODULATE_FUSION: "1"
H3_NVFP4_SWIGLU_FUSION: "1"
H3_NVFP4_FC2_LT_SPLITK1: "1"
H3_SAGE_QKV_LAYOUT: "strided_nhd"
H3_SOL_QKV_LAYOUT: "native"
command: ["python", "/opt/h3-blackwell-runtime/tools/serve_hot_runtime.py", "--host", "0.0.0.0", "--port", "8000", "--attention", "sage2", "--turbo-lora", "4step=/turbo/minimax_h3_fl2v_turbo_4step_v1.1_768p_comfyui_bf16.safetensors", "--turbo-lora", "8step=/turbo/minimax_h3_fl2v_turbo_8step_v1.0_comfyui_bf16.safetensors", "--latent-upscaler", "/latent-upscaler/minimax_h3_latent_upscaler_3d_fp16.safetensors", "--warmup"]

View file

@ -17,3 +17,6 @@ flash4 = ["flash-attn-4[cu13]==4.0.0b27"]
[tool.setuptools.packages.find]
where = ["src"]
[tool.setuptools.package-data]
h3_blackwell_runtime = ["csrc/*.cpp", "csrc/*.cu"]

View file

@ -2,36 +2,36 @@
"metadata": {
"algorithm": "SHA-256",
"generated_date": "2026-08-25",
"scope_note": "Local selected scope is the established 167-file set plus 10 retained FC2 scheduling artifacts. Spark records are the complete reproducible current top-level benchmark output set; the audit-retained 279-file/665950155-byte aggregate cannot be reconstructed because its path list was not retained.",
"scope_note": "Local selected scope is the established 167-file set plus 14 retained FC2 scheduling and integration artifacts. Spark records are the complete reproducible current top-level benchmark output set; the audit-retained 279-file/665950155-byte aggregate cannot be reconstructed because its path list was not retained.",
"summary": {
"local": {
"record_count": 177,
"size_bytes": 230157548,
"expected_record_count": 177,
"expected_size_bytes": 230157548,
"record_count": 181,
"size_bytes": 230398680,
"expected_record_count": 181,
"expected_size_bytes": 230398680,
"reconciled": true
},
"spark": {
"record_count": 290,
"size_bytes": 567477443,
"record_count": 294,
"size_bytes": 567718575,
"expected_record_count": 279,
"expected_size_bytes": 665950155,
"reconciled": false,
"record_count_delta": 11,
"size_bytes_delta": -98472712
"record_count_delta": 15,
"size_bytes_delta": -98231580
},
"total": {
"record_count": 467,
"size_bytes": 797634991
"record_count": 475,
"size_bytes": 798117255
}
},
"json_reconciliation": {
"identical": 112,
"mismatches": 2,
"identical": 118,
"mismatches": 0,
"local_only": 40,
"spark_only": 107,
"local_total": 154,
"spark_total": 221
"local_total": 158,
"spark_total": 225
}
},
"artifacts": [
@ -195,6 +195,70 @@
"artifact_class": "benchmark_json",
"location": "/home/daniel/StoryStudioAssets/H3-output/h3-blackwell-runtime/benchmarks/gb10-fc2-nvfp4-trajectory-2step-20260825.json"
},
{
"scope": "local",
"path": "benchmarks/gb10-fc2-nvfp4-production-block-gate-20260825.json",
"size_bytes": 61575,
"sha256": "a49664031af6c21a341cfb0787000e54801c4067cf8ad231cc614c11de251067",
"artifact_class": "benchmark_json",
"location": "benchmarks/gb10-fc2-nvfp4-production-block-gate-20260825.json"
},
{
"scope": "local",
"path": "benchmarks/gb10-fc2-nvfp4-production-trajectory-2step-20260825.json",
"size_bytes": 53189,
"sha256": "3e0e42addf5a748462f1bc600d5bb08875b31da5177d2af2b2abddfb1078ebd3",
"artifact_class": "benchmark_json",
"location": "benchmarks/gb10-fc2-nvfp4-production-trajectory-2step-20260825.json"
},
{
"scope": "local",
"path": "benchmarks/gb10-fc2-nvfp4-production-trajectory-12step-20260825.json",
"size_bytes": 53192,
"sha256": "94a915acee1bf3d3c23a934f93bafc583ac2ae0f3e91ff1277ee57f628e2d254",
"artifact_class": "benchmark_json",
"location": "benchmarks/gb10-fc2-nvfp4-production-trajectory-12step-20260825.json"
},
{
"scope": "local",
"path": "benchmarks/gb10-fc2-nvfp4-shape-gate-20260825.json",
"size_bytes": 73176,
"sha256": "cbde2aab33ceb9df32e65c8649838dcdf47e0e135aaaae4165b2f9b6e8d2734b",
"artifact_class": "benchmark_json",
"location": "benchmarks/gb10-fc2-nvfp4-shape-gate-20260825.json"
},
{
"scope": "spark",
"path": "/home/daniel/StoryStudioAssets/H3-output/h3-blackwell-runtime/benchmarks/gb10-fc2-nvfp4-production-block-gate-20260825.json",
"size_bytes": 61575,
"sha256": "a49664031af6c21a341cfb0787000e54801c4067cf8ad231cc614c11de251067",
"artifact_class": "benchmark_json",
"location": "/home/daniel/StoryStudioAssets/H3-output/h3-blackwell-runtime/benchmarks/gb10-fc2-nvfp4-production-block-gate-20260825.json"
},
{
"scope": "spark",
"path": "/home/daniel/StoryStudioAssets/H3-output/h3-blackwell-runtime/benchmarks/gb10-fc2-nvfp4-production-trajectory-2step-20260825.json",
"size_bytes": 53189,
"sha256": "3e0e42addf5a748462f1bc600d5bb08875b31da5177d2af2b2abddfb1078ebd3",
"artifact_class": "benchmark_json",
"location": "/home/daniel/StoryStudioAssets/H3-output/h3-blackwell-runtime/benchmarks/gb10-fc2-nvfp4-production-trajectory-2step-20260825.json"
},
{
"scope": "spark",
"path": "/home/daniel/StoryStudioAssets/H3-output/h3-blackwell-runtime/benchmarks/gb10-fc2-nvfp4-production-trajectory-12step-20260825.json",
"size_bytes": 53192,
"sha256": "94a915acee1bf3d3c23a934f93bafc583ac2ae0f3e91ff1277ee57f628e2d254",
"artifact_class": "benchmark_json",
"location": "/home/daniel/StoryStudioAssets/H3-output/h3-blackwell-runtime/benchmarks/gb10-fc2-nvfp4-production-trajectory-12step-20260825.json"
},
{
"scope": "spark",
"path": "/home/daniel/StoryStudioAssets/H3-output/h3-blackwell-runtime/benchmarks/gb10-fc2-nvfp4-shape-gate-20260825.json",
"size_bytes": 73176,
"sha256": "cbde2aab33ceb9df32e65c8649838dcdf47e0e135aaaae4165b2f9b6e8d2734b",
"artifact_class": "benchmark_json",
"location": "/home/daniel/StoryStudioAssets/H3-output/h3-blackwell-runtime/benchmarks/gb10-fc2-nvfp4-shape-gate-20260825.json"
},
{
"scope": "local",
"path": "benchmarks/audio-dialogue-format-sweep-sage2-seeds440420-440429.json",

View file

@ -504,22 +504,22 @@
"id": "fc2-cublaslt-splitk1-schedule",
"name": "FC2 cuBLASLt public split-K-1 schedule",
"family": "nvfp4-library-scheduling",
"status": "research_retained",
"status": "production_accepted",
"hypothesis": "A documented cuBLASLt schedule can preserve the exact FC2 reduction result while avoiding the production heuristic's traffic and synchronization regression.",
"implementation_strategy": "Reproduce the exact Comfy Kitchen descriptors in an isolated extension, enumerate checked cuBLASLt algorithms, and compare one selected public split-K-1 schedule against the accepted FC2 path.",
"source_locations": ["research/fc2_nvfp4_scheduling/README.md", "research/fc2_nvfp4_scheduling/RESULTS.md", "research/fc2_nvfp4_scheduling/fc2_nvfp4_lt.cpp", "tools/benchmark_fc2_nvfp4_algorithms.py"],
"active_source_location": "research/fc2_nvfp4_scheduling/fc2_nvfp4_lt.cpp",
"source_locations": ["research/fc2_nvfp4_scheduling/README.md", "research/fc2_nvfp4_scheduling/RESULTS.md", "src/h3_blackwell_runtime/csrc/fc2_nvfp4_lt.cpp", "tools/benchmark_fc2_nvfp4_algorithms.py"],
"active_source_location": "src/h3_blackwell_runtime/csrc/fc2_nvfp4_lt.cpp",
"commit_hash": null,
"benchmark_artifacts": [{"path": "benchmarks/gb10-fc2-nvfp4-library-sweep-20260825.json", "exists": true}, {"path": "benchmarks/gb10-fc2-nvfp4-block-gate-20260825.json", "exists": true}, {"path": "benchmarks/gb10-fc2-nvfp4-trajectory-2step-20260825.json", "exists": true}, {"path": "benchmarks/gb10-fc2-nvfp4-trajectory-12step-20260825.json", "exists": true}],
"benchmark_artifacts": [{"path": "benchmarks/gb10-fc2-nvfp4-library-sweep-20260825.json", "exists": true}, {"path": "benchmarks/gb10-fc2-nvfp4-production-block-gate-20260825.json", "exists": true}, {"path": "benchmarks/gb10-fc2-nvfp4-production-trajectory-2step-20260825.json", "exists": true}, {"path": "benchmarks/gb10-fc2-nvfp4-production-trajectory-12step-20260825.json", "exists": true}, {"path": "benchmarks/gb10-fc2-nvfp4-shape-gate-20260825.json", "exists": true}],
"profiler_artifacts": [{"path": "benchmarks/gb10-fc2-nvfp4-baseline-20260825.ncu-rep", "exists": true}, {"path": "benchmarks/gb10-fc2-nvfp4-splitk1-20260825.ncu-rep", "exists": true}, {"path": "benchmarks/gb10-fc2-nvfp4-baseline-20260825.csv", "exists": true}, {"path": "benchmarks/gb10-fc2-nvfp4-splitk1-20260825.csv", "exists": true}],
"environment": {"gpu": "NVIDIA GB10", "cuda": "13", "driver": null, "pytorch": null, "triton": null, "container_image": "sha256:1d340e14cb6fc45ccfdbe63dde8db2a2b3aea94b493702c8a08e1f8d5b4f7b83", "commit_context": "isolated extension; production source and dispatch unchanged"},
"metrics": {"fc2_p50_ms_baseline": 53.618, "fc2_p50_ms_candidate": 15.636, "block_improvement_pct": [8.16, 8.63, 8.88], "two_step_improvement_pct": 7.50, "canonical_12_step_improvement_pct": 8.21, "trajectory_measurement_note": "single baseline-then-candidate paired runs", "l2_hit_rate_pct_baseline": 53.32, "l2_hit_rate_pct_candidate": 91.10, "l2_read_miss_reduction_bytes": 9853094784},
"correctness_evidence": ["Selected FC2 output is byte-exact.", "Blocks 0, 24, and 49 are byte-exact against paired baseline and retained traversal.", "Two-step and canonical 12-step video and audio latents are byte-exact."],
"decision_rationale": "The library schedule passed all exactness and performance gates, explaining the prior traffic amplification without requiring a custom kernel. It is retained pending explicit production integration and deployment validation.",
"reproducer_commands": ["python tools/benchmark_fc2_nvfp4_algorithms.py --mode sweep --rounds 20 --workspace-bytes 67108864", "python tools/benchmark_fc2_nvfp4_algorithms.py --mode block-gate --candidate research/fc2_nvfp4_scheduling/candidate_splitk1.json --rounds 20 --workspace-bytes 0"],
"environment": {"gpu": "NVIDIA GB10", "cuda": "13", "driver": null, "pytorch": "2.9.1+cu130", "triton": null, "container_image": "sha256:d61c8d29e8b59306d140bfd279b0de31d827ad13bd92447ea72ea0a04182494d", "commit_context": "guarded canonical production integration"},
"metrics": {"fc2_p50_ms_baseline": 53.618, "fc2_p50_ms_candidate": 15.636, "production_block_improvement_pct": [9.36, 8.16, 7.86], "production_two_step_seconds": {"baseline": 47.30056222799976, "candidate": 43.727866895999796, "improvement_percent": 7.553177306389591}, "production_canonical_12_step_seconds": {"baseline": 286.43065266899976, "candidate": 262.97871506399997, "improvement_percent": 8.187649396624085}, "production_12_step_dispatches": 600, "production_12_step_fallbacks": 0, "l2_hit_rate_pct_baseline": 53.32, "l2_hit_rate_pct_candidate": 91.10, "l2_read_miss_reduction_bytes": 9853094784},
"correctness_evidence": ["Production blocks 0, 24, and 49 are byte-exact against paired baseline and retained traversal.", "Production two-step and canonical 12-step video and audio latents are byte-exact.", "Nearby M=37711/37725/37742 shape probes differ in two BF16 elements and are excluded by the canonical guard."],
"decision_rationale": "The shape-guarded library schedule passed production-method block and trajectory gates without requiring a custom kernel. Noncanonical shapes retain the accepted fallback because AlgoCheck alone does not guarantee byte exactness.",
"reproducer_commands": ["python tools/benchmark_fc2_nvfp4_algorithms.py --mode production-block-gate --candidate research/fc2_nvfp4_scheduling/candidate_splitk1.json --rounds 20 --workspace-bytes 0", "python tools/benchmark_fc2_nvfp4_algorithms.py --mode production-trajectory --candidate research/fc2_nvfp4_scheduling/candidate_splitk1.json --steps 12 --workspace-bytes 0", "python tools/benchmark_fc2_nvfp4_algorithms.py --mode shape-gate --candidate research/fc2_nvfp4_scheduling/candidate_splitk1.json --workspace-bytes 0"],
"timestamp": "2026-08-25",
"evidence_missing": ["Production Nvfp4Linear integration", "Production deployment smoke", "Portable validation outside GB10/SM121"],
"production_behavior": "Not dispatched. Production still uses Comfy Kitchen's heuristic-selected FC2 path.",
"evidence_missing": ["Resident-service deployment validation deferred until performance work completes", "Trajectory timings are single baseline-then-candidate pairs rather than repeated AB/BA trials", "Shape-gate artifact predates runtime-version fields in build_info", "Portable validation outside GB10/SM121"],
"production_behavior": "H3_NVFP4_FC2_LT_SPLITK1 selects algorithm 70 only for the validated canonical FC2 descriptor; every other shape, device, library, LoRA, and failure case falls back to Comfy Kitchen.",
"source_recovery": "The direct cuBLASLt extension, benchmark harness, selected candidate, raw NCU reports, and full gate artifacts are retained in this checkout."
},
{

View file

@ -1,14 +1,15 @@
# FC2 NVFP4 Library Scheduling
This directory contains the first isolated library-scheduling study for H3 FC2.
It does not register a PyTorch operator, alter `Nvfp4Linear`, or participate in
production dispatch. The extension is loaded only by
`tools/benchmark_fc2_nvfp4_algorithms.py`.
The validated extension source moved to
`src/h3_blackwell_runtime/csrc/fc2_nvfp4_lt.cpp` when the guarded production
integration was added. The research harness and production loader share that
source.
The completed measurements and decision are in `RESULTS.md`. Algorithm 70 with
public split-K 1 is byte-exact and passes the block, two-step, and canonical
12-step gates, but remains research-only until production integration and
deployment validation are performed.
12-step gates. Canonical-only production integration is complete behind an
opt-in flag; resident-service deployment validation remains deferred.
## Exact Operation
@ -175,6 +176,10 @@ latents; see `RESULTS.md` and the linked benchmark artifacts.
## Prohibited Experiments
These restrictions governed the isolated study. Production integration was
authorized only after the library candidate passed the complete validation
ladder; the canonical-only guard and automatic fallback preserve that boundary.
- Do not alter production source, configuration, dispatch, or existing
research files.
- Do not expose this extension through `Nvfp4Linear` or any production operator.

View file

@ -1,7 +1,7 @@
# FC2 NVFP4 Scheduling Results
Status: research retained; validated as a canonical-shape production-integration
candidate, but not wired into production dispatch.
Status: production accepted for the canonical descriptor shape behind
`H3_NVFP4_FC2_LT_SPLITK1`; all other shapes retain the existing fallback.
## Decision
@ -70,13 +70,52 @@ traversal.
| Canonical 12-step | `278.201 s` | `255.371 s` | `8.21%` | video/audio BF16 exact |
Trajectory values are single paired runs in baseline-then-candidate
order, not repeated medians. Their approximately `38 ms` per-FC2 savings agree
order, not repeated medians or AB/BA trials. Their approximately `38 ms` per-FC2 savings agree
with the alternating isolated and complete-block gates, but the precise
end-to-end percentages retain run-order uncertainty.
The 12-step saving of `22.829 s` matches approximately 600 FC2 invocations
multiplied by the isolated roughly `38 ms` saving.
## Production Integration
The packaged path lives in `src/h3_blackwell_runtime/fc2_lt.py` and is called
from `Nvfp4Linear.forward_swiglu` only after the accepted native producer. It
requires the FC2 role, unsharded `K=14,336/N=5,376`, BF16 output, no bias or
active LoRA, GB10/SM121, CUDA 13.0, cuBLAS 13.1 headers, cuBLASLt 13.0 runtime,
logical `M=37,810`, and packed
`M=37,824`. A shape-specific `cublasLtMatmulAlgoCheck` must pass with zero
workspace. Load, check, or execution failure falls back through the already
produced NVFP4 bytes without quantizing twice; strict mode is available through
`H3_NVFP4_FC2_LT_STRICT=1`. Production startup prepares the extension and
caches its measured runtime compatibility result before inference.
The 20-round production-method gate exercised `Nvfp4Linear.forward_swiglu`
directly and recorded 23 successful dispatches with zero fallbacks per block:
| Block | Baseline p50 | Production p50 | Improvement |
| ---: | ---: | ---: | ---: |
| 0 | `464.153 ms` | `420.714 ms` | `9.36%` |
| 24 | `460.184 ms` | `422.656 ms` | `8.16%` |
| 49 | `456.183 ms` | `420.335 ms` | `7.86%` |
Production-method trajectories remained exact:
| Trajectory | Baseline | Production | Improvement | Dispatch |
| --- | ---: | ---: | ---: | --- |
| Two-step | `47.301 s` | `43.728 s` | `7.55%` | `100/100`, zero fallback |
| Canonical 12-step | `286.431 s` | `262.979 s` | `8.19%` | `600/600`, zero fallback |
The row-shape gate prevents unsafe generalization. Algorithm 70 was exact for
the tested `M=37,774`, `37,809`, `37,810`, `37,838`, `37,966`, and `38,222`
inputs, but differed in two BF16 elements at each of `M=37,711`, `37,725`, and
`37,742` despite passing `AlgoCheck`. Production therefore intentionally keeps
the canonical-only guard rather than inferring exactness from nearby shapes.
The retained shape artifact records compile-time CUDA/cuBLAS versions but
predates runtime-version fields in `build_info()`. The final extension separately
measured CUDA runtime `13000` and cuBLASLt runtime `130000`; the shape artifact
alone is not runtime-ABI evidence.
## Traffic Attribution
The one-pass distinct-data footprint is:
@ -150,9 +189,12 @@ synchronization waiting, not occupancy or a reduction workspace.
- `benchmarks/gb10-fc2-nvfp4-splitk1-20260825.csv`
- `benchmarks/gb10-fc2-nvfp4-baseline-20260825.ncu-rep`
- `benchmarks/gb10-fc2-nvfp4-splitk1-20260825.ncu-rep`
- `benchmarks/gb10-fc2-nvfp4-production-block-gate-20260825.json`
- `benchmarks/gb10-fc2-nvfp4-production-trajectory-2step-20260825.json`
- `benchmarks/gb10-fc2-nvfp4-production-trajectory-12step-20260825.json`
- `benchmarks/gb10-fc2-nvfp4-shape-gate-20260825.json`
- `src/h3_blackwell_runtime/csrc/fc2_nvfp4_lt.cpp`
Production source and configuration were not changed by this study. The
candidate is validated only for the canonical descriptor shape and current
GB10/CUDA-library combination. Promotion still requires shape-specific
`AlgoCheck` with a safe fallback, integration behind the existing
`Nvfp4Linear` boundary, broader shape tests, and deployment validation.
The Spark hot runtime remains stopped while performance work continues.
Resident-service validation is intentionally deferred until the performance
program is finished.

View file

@ -23,13 +23,22 @@ namespace py = pybind11;
namespace {
thread_local cublasLtHandle_t handle = nullptr;
struct LtHandle {
cublasLtHandle_t value = nullptr;
LtHandle() { LT_CHECK(cublasLtCreate(&value)); }
~LtHandle() {
if (value) cublasLtDestroy(value);
}
};
cublasLtHandle_t get_handle() {
if (!handle) LT_CHECK(cublasLtCreate(&handle));
return handle;
static LtHandle handle;
return handle.value;
}
void prepare() { get_handle(); }
void require_cuda_contiguous(const torch::Tensor& tensor, const char* name) {
TORCH_CHECK(tensor.is_cuda(), name, " must be CUDA");
TORCH_CHECK(tensor.is_contiguous(), name, " must be contiguous");
@ -50,6 +59,19 @@ struct Problem {
const torch::Tensor& activation_block_scale,
const torch::Tensor& weight_qdata,
const torch::Tensor& weight_block_scale) {
try {
initialize(activation_qdata, activation_block_scale, weight_qdata,
weight_block_scale);
} catch (...) {
reset();
throw;
}
}
void initialize(const torch::Tensor& activation_qdata,
const torch::Tensor& activation_block_scale,
const torch::Tensor& weight_qdata,
const torch::Tensor& weight_block_scale) {
require_cuda_contiguous(activation_qdata, "activation_qdata");
require_cuda_contiguous(activation_block_scale, "activation_block_scale");
require_cuda_contiguous(weight_qdata, "weight_qdata");
@ -122,13 +144,17 @@ struct Problem {
LT_CHECK(cublasLtMatrixLayoutCreate(&d, CUDA_R_16BF, m, n, m));
}
~Problem() {
void reset() noexcept {
if (d) cublasLtMatrixLayoutDestroy(d);
if (c) cublasLtMatrixLayoutDestroy(c);
if (b) cublasLtMatrixLayoutDestroy(b);
if (a) cublasLtMatrixLayoutDestroy(a);
if (operation) cublasLtMatmulDescDestroy(operation);
d = c = b = a = nullptr;
operation = nullptr;
}
~Problem() { reset(); }
};
template <typename T>
@ -367,8 +393,15 @@ void run(torch::Tensor activation_qdata,
py::dict build_info() {
py::dict result;
int cuda_runtime_version = 0;
const cudaError_t cuda_status = cudaRuntimeGetVersion(&cuda_runtime_version);
TORCH_CHECK(cuda_status == cudaSuccess, "cudaRuntimeGetVersion failed: ",
cudaGetErrorString(cuda_status));
result["cuda_version"] = CUDA_VERSION;
result["cublas_version"] = CUBLAS_VERSION;
result["cuda_runtime_version"] = cuda_runtime_version;
result["cublaslt_runtime_version"] =
static_cast<int64_t>(cublasLtGetVersion());
result["stream_k_public_control"] = false;
result["stream_k_note"] =
"CUDA 13 cuBLASLt exposes no documented MatmulAlgoConfig attribute "
@ -381,6 +414,7 @@ py::dict build_info() {
} // namespace
PYBIND11_MODULE(TORCH_EXTENSION_NAME, module) {
module.def("prepare", &prepare);
module.def("enumerate", &enumerate);
module.def("check", &check);
module.def("run", &run);

View file

@ -0,0 +1,197 @@
"""Guarded production dispatch for the canonical GB10 FC2 cuBLASLt schedule."""
from __future__ import annotations
import os
from functools import lru_cache
from pathlib import Path
import torch
_TRUTHY = {"1", "true", "yes", "on"}
_CANONICAL_LOGICAL_SHAPE = (37_810, 14_336, 5_376)
_CANONICAL_PACKED_ROWS = 37_824
_CONFIG = {
"algorithm_id": 70,
"tile_id": 20,
"stages_id": 37,
"split_k": 1,
"reduction_scheme": 0,
"custom_option": 0,
"cta_swizzle": 0,
}
_VALIDATED: set[tuple[int, tuple[int, ...], tuple[int, ...]]] = set()
_STATS = {"attempts": 0, "successes": 0, "fallbacks": 0}
class _Fc2LtStrictError(RuntimeError):
pass
def fc2_lt_enabled() -> bool:
return os.getenv("H3_NVFP4_FC2_LT_SPLITK1", "").lower() in _TRUTHY
def _fc2_lt_strict() -> bool:
return os.getenv("H3_NVFP4_FC2_LT_STRICT", "").lower() in _TRUTHY
def fc2_lt_status() -> dict:
return {"enabled": fc2_lt_enabled(), **_STATS}
@lru_cache(maxsize=1)
def _fc2_lt_extension():
from torch.utils.cpp_extension import CUDA_HOME, load
if CUDA_HOME is None:
raise RuntimeError("CUDA_HOME is unavailable")
source = Path(__file__).resolve().parent / "csrc" / "fc2_nvfp4_lt.cpp"
return load(
name="h3_fc2_nvfp4_lt",
sources=[str(source)],
extra_include_paths=[str(Path(CUDA_HOME) / "include")],
extra_cflags=["-O2", "-std=c++17"],
extra_ldflags=[
"-L" + str(Path(CUDA_HOME) / "lib64"),
"-lcublasLt",
"-lcublas",
"-lcudart",
],
verbose=os.getenv("H3_NVFP4_FC2_LT_VERBOSE", "").lower() in _TRUTHY,
)
@lru_cache(maxsize=1)
def _fc2_lt_extension_result():
try:
return _fc2_lt_extension(), None
except Exception as error:
return None, error
@lru_cache(maxsize=1)
def _fc2_lt_compatible_result():
extension, load_error = _fc2_lt_extension_result()
if extension is None:
return None, load_error
try:
info = dict(extension.build_info())
compatible = (
info.get("cuda_version") == 13_000
and info.get("cublas_version") == 130_100
and info.get("cuda_runtime_version") == 13_000
and info.get("cublaslt_runtime_version") == 130_000
)
if not compatible:
return None, RuntimeError(f"unsupported FC2 cuBLASLt environment: {info}")
extension.prepare()
return extension, None
except Exception as error:
return None, error
def _canonical_fc2_supported(linear, gate_up: torch.Tensor, qdata: torch.Tensor) -> bool:
logical_rows, in_features, out_features = _CANONICAL_LOGICAL_SHAPE
return (
linear.role == "h3_mlp_fc2"
and linear.in_features == in_features
and linear.out_features == out_features
and linear.output_dtype == torch.bfloat16
and linear.bias is None
and tuple(gate_up.shape) == (logical_rows, in_features * 2)
and tuple(qdata.shape) == (_CANONICAL_PACKED_ROWS, in_features // 2)
and torch.cuda.get_device_capability(gate_up.device) == (12, 1)
)
def _fallback_or_raise(message: str, error: Exception | None = None):
_STATS["fallbacks"] += 1
if _fc2_lt_strict():
if error is None:
raise _Fc2LtStrictError(message)
raise _Fc2LtStrictError(message) from error
return None
def prepare_fc2_lt() -> bool:
"""Load and validate the extension before latency-sensitive inference."""
if not fc2_lt_enabled():
return False
extension, error = _fc2_lt_compatible_result()
if extension is None:
_fallback_or_raise("FC2 cuBLASLt extension is incompatible", error)
return False
return True
def fc2_lt_linear(
linear,
gate_up: torch.Tensor,
tensor_scale: torch.Tensor,
qdata: torch.Tensor,
block_scale: torch.Tensor,
) -> torch.Tensor | None:
"""Run the validated canonical schedule, or return ``None`` for fallback."""
if not fc2_lt_enabled():
return None
try:
supported = _canonical_fc2_supported(linear, gate_up, qdata)
except Exception as error:
return _fallback_or_raise("FC2 cuBLASLt eligibility check failed", error)
if not supported:
_STATS["fallbacks"] += 1
return None
_STATS["attempts"] += 1
extension, load_error = _fc2_lt_compatible_result()
if extension is None:
return _fallback_or_raise(
"FC2 cuBLASLt extension failed to load or is incompatible", load_error
)
try:
device = gate_up.device.index if gate_up.device.index is not None else torch.cuda.current_device()
validation_key = (device, tuple(qdata.shape), tuple(linear.weight.shape))
if validation_key not in _VALIDATED:
checked = dict(
extension.check(
qdata,
block_scale,
linear.weight,
linear.weight_scale,
_CONFIG,
)
)
if not checked.get("valid") or checked.get("required_workspace_bytes") != 0:
return _fallback_or_raise(
f"FC2 cuBLASLt algorithm check rejected the candidate: {checked}"
)
_VALIDATED.add(validation_key)
alpha = (tensor_scale.float() * linear.weight_scale_2.float()).reshape(1).contiguous()
beta = torch.zeros_like(alpha)
output = torch.empty(
(qdata.shape[0], linear.out_features),
device=qdata.device,
dtype=torch.bfloat16,
)
workspace = torch.empty(0, device=qdata.device, dtype=torch.uint8)
extension.run(
qdata,
block_scale,
linear.weight,
linear.weight_scale,
alpha,
beta,
output,
workspace,
_CONFIG,
)
_STATS["successes"] += 1
return output[: gate_up.shape[0], : linear.out_features]
except _Fc2LtStrictError:
raise
except Exception as error:
return _fallback_or_raise("FC2 cuBLASLt candidate execution failed", error)

View file

@ -164,9 +164,16 @@ class Nvfp4Linear(DynamicLoraMixin, nn.Module):
if gate_up.dtype != torch.bfloat16 or not gate_up.is_cuda or not gate_up.is_contiguous():
raise ValueError("SwiGLU NVFP4 dispatch requires contiguous CUDA BF16 input")
from .nvfp4_quant import vortex_quantize_swiglu_nvfp4
from .nvfp4_quant import vortex_native_quantize_swiglu_nvfp4, wrap_native_swiglu_nvfp4
packed_x = vortex_quantize_swiglu_nvfp4(gate_up)
packed = vortex_native_quantize_swiglu_nvfp4(gate_up)
if os.getenv("H3_NVFP4_FC2_LT_SPLITK1", "").lower() in {"1", "true", "yes", "on"}:
from .fc2_lt import fc2_lt_linear
scheduled = fc2_lt_linear(self, gate_up, *packed)
if scheduled is not None:
return scheduled
packed_x = wrap_native_swiglu_nvfp4(gate_up, packed)
bias = self.bias.to(gate_up) if self.bias is not None else None
output = functional.linear(packed_x, self._packed_weight(), bias)[
: gate_up.shape[0], : self.out_features

View file

@ -328,9 +328,16 @@ def vortex_native_quantize_swiglu_nvfp4(tensor: torch.Tensor):
def vortex_quantize_swiglu_nvfp4(tensor: torch.Tensor):
"""Wrap fused SwiGLU output as a Comfy TensorCoreNVFP4Layout tensor."""
return wrap_native_swiglu_nvfp4(
tensor, vortex_native_quantize_swiglu_nvfp4(tensor),
)
def wrap_native_swiglu_nvfp4(tensor: torch.Tensor, packed):
"""Wrap already-produced fused SwiGLU bytes for the Comfy fallback."""
from comfy_kitchen.tensor import QuantizedTensor, TensorCoreNVFP4Layout
tensor_scale, qdata, block_scale = vortex_native_quantize_swiglu_nvfp4(tensor)
tensor_scale, qdata, block_scale = packed
output_shape = (tensor.shape[0], tensor.shape[1] // 2)
return QuantizedTensor(
qdata,

View file

@ -154,9 +154,14 @@ class H3HotRuntime:
def _load_h3(self) -> H3PackedDenoiser:
model = H3PackedDenoiser.from_checkpoint(self.checkpoint, attention_backend=self.config.attention).eval()
configure_mlp_chunking(model, self.config.mlp_chunks, self.config.mlp_chunk_threshold)
from .fc2_lt import prepare_fc2_lt
prepare_fc2_lt()
return model
def status(self) -> dict:
from .fc2_lt import fc2_lt_status
return {
"ready": True,
"initial_attention": self.config.attention,
@ -168,6 +173,7 @@ class H3HotRuntime:
"vae_tile_size": self.config.vae_tile_size,
"mlp_chunks": self.config.mlp_chunks,
"mlp_chunk_threshold": self.config.mlp_chunk_threshold,
"fc2_lt": fc2_lt_status(),
"loaded_at": self.loaded_at,
"load_stages": self.load_stages,
}

287
tests/test_fc2_lt.py Normal file
View file

@ -0,0 +1,287 @@
import os
import unittest
from types import SimpleNamespace
from unittest.mock import MagicMock, patch
import torch
from h3_blackwell_runtime.fc2_lt import (
_VALIDATED,
_canonical_fc2_supported,
_fc2_lt_compatible_result,
_STATS,
fc2_lt_enabled,
fc2_lt_linear,
prepare_fc2_lt,
)
from h3_blackwell_runtime.nvfp4 import Nvfp4Linear
from h3_blackwell_runtime.runtime import H3HotRuntime
class Fc2LtContracts(unittest.TestCase):
def setUp(self):
_VALIDATED.clear()
_fc2_lt_compatible_result.cache_clear()
_STATS.update(attempts=0, successes=0, fallbacks=0)
def test_flag_is_opt_in(self):
with patch.dict(os.environ, {}, clear=True):
self.assertFalse(fc2_lt_enabled())
with patch.dict(os.environ, {"H3_NVFP4_FC2_LT_SPLITK1": "yes"}, clear=True):
self.assertTrue(fc2_lt_enabled())
def test_only_canonical_unsharded_fc2_is_eligible(self):
linear = SimpleNamespace(
role="h3_mlp_fc2",
in_features=14_336,
out_features=5_376,
output_dtype=torch.bfloat16,
bias=None,
)
gate_up = SimpleNamespace(
shape=(37_810, 28_672),
device=torch.device("cuda", 0),
)
qdata = SimpleNamespace(shape=(37_824, 7_168))
with patch("torch.cuda.get_device_capability", return_value=(12, 1)):
self.assertTrue(_canonical_fc2_supported(linear, gate_up, qdata))
linear.in_features //= 2
self.assertFalse(_canonical_fc2_supported(linear, gate_up, qdata))
def test_prepare_loads_and_validates_extension(self):
extension = MagicMock()
extension.build_info.return_value = {
"cuda_version": 13_000,
"cublas_version": 130_100,
"cuda_runtime_version": 13_000,
"cublaslt_runtime_version": 130_000,
}
with (
patch.dict(os.environ, {"H3_NVFP4_FC2_LT_SPLITK1": "1"}, clear=True),
patch(
"h3_blackwell_runtime.fc2_lt._fc2_lt_extension_result",
return_value=(extension, None),
),
):
self.assertTrue(prepare_fc2_lt())
extension.prepare.assert_called_once_with()
def test_ineligible_shape_is_counted_as_fallback(self):
args = (MagicMock(), MagicMock(), MagicMock(), MagicMock(), MagicMock())
with (
patch.dict(os.environ, {"H3_NVFP4_FC2_LT_SPLITK1": "1"}, clear=True),
patch("h3_blackwell_runtime.fc2_lt._canonical_fc2_supported", return_value=False),
):
self.assertIsNone(fc2_lt_linear(*args))
self.assertEqual(_STATS["fallbacks"], 1)
def test_h3_model_load_prepares_extension(self):
model = MagicMock()
model.eval.return_value = model
runtime = SimpleNamespace(
checkpoint=MagicMock(),
config=SimpleNamespace(attention="sage2", mlp_chunks=1, mlp_chunk_threshold=4096),
)
with (
patch(
"h3_blackwell_runtime.runtime.H3PackedDenoiser.from_checkpoint",
return_value=model,
),
patch("h3_blackwell_runtime.runtime.configure_mlp_chunking") as configure,
patch("h3_blackwell_runtime.fc2_lt.prepare_fc2_lt") as prepare,
):
self.assertIs(H3HotRuntime._load_h3(runtime), model)
configure.assert_called_once_with(model, 1, 4096)
prepare.assert_called_once_with()
def test_extension_load_failure_falls_back_unless_strict(self):
args = (MagicMock(), MagicMock(), MagicMock(), MagicMock(), MagicMock())
with (
patch.dict(os.environ, {"H3_NVFP4_FC2_LT_SPLITK1": "1"}, clear=True),
patch("h3_blackwell_runtime.fc2_lt._canonical_fc2_supported", return_value=True),
patch("h3_blackwell_runtime.fc2_lt._fc2_lt_extension_result", return_value=(None, RuntimeError("load"))),
):
self.assertIsNone(fc2_lt_linear(*args))
with (
patch.dict(os.environ, {"H3_NVFP4_FC2_LT_SPLITK1": "1", "H3_NVFP4_FC2_LT_STRICT": "1"}, clear=True),
patch("h3_blackwell_runtime.fc2_lt._canonical_fc2_supported", return_value=True),
patch("h3_blackwell_runtime.fc2_lt._fc2_lt_extension_result", return_value=(None, RuntimeError("load"))),
):
with self.assertRaisesRegex(RuntimeError, "failed to load"):
fc2_lt_linear(*args)
def test_build_info_and_runtime_version_failures_fall_back(self):
extension = MagicMock()
extension.build_info.side_effect = RuntimeError("metadata")
args = (MagicMock(), MagicMock(), MagicMock(), MagicMock(), MagicMock())
with (
patch.dict(os.environ, {"H3_NVFP4_FC2_LT_SPLITK1": "1"}, clear=True),
patch("h3_blackwell_runtime.fc2_lt._canonical_fc2_supported", return_value=True),
patch("h3_blackwell_runtime.fc2_lt._fc2_lt_extension_result", return_value=(extension, None)),
):
self.assertIsNone(fc2_lt_linear(*args))
_fc2_lt_compatible_result.cache_clear()
extension.build_info.side_effect = None
extension.build_info.return_value = {
"cuda_version": 13_000,
"cublas_version": 130_100,
"cuda_runtime_version": 12_900,
"cublaslt_runtime_version": 130_000,
}
with (
patch.dict(os.environ, {"H3_NVFP4_FC2_LT_SPLITK1": "1"}, clear=True),
patch("h3_blackwell_runtime.fc2_lt._canonical_fc2_supported", return_value=True),
patch("h3_blackwell_runtime.fc2_lt._fc2_lt_extension_result", return_value=(extension, None)),
):
self.assertIsNone(fc2_lt_linear(*args))
def test_algo_check_and_execution_failures_fall_back(self):
extension = MagicMock()
extension.build_info.return_value = {
"cuda_version": 13_000,
"cublas_version": 130_100,
"cuda_runtime_version": 13_000,
"cublaslt_runtime_version": 130_000,
}
linear = MagicMock()
linear.weight.shape = (5_376, 7_168)
gate_up = MagicMock()
gate_up.device.index = 0
qdata = MagicMock()
qdata.shape = (37_824, 7_168)
args = (linear, gate_up, MagicMock(), qdata, MagicMock())
common = (
patch.dict(os.environ, {"H3_NVFP4_FC2_LT_SPLITK1": "1"}, clear=True),
patch("h3_blackwell_runtime.fc2_lt._canonical_fc2_supported", return_value=True),
patch("h3_blackwell_runtime.fc2_lt._fc2_lt_extension_result", return_value=(extension, None)),
)
extension.check.return_value = {"valid": False, "required_workspace_bytes": 0}
with common[0], common[1], common[2]:
self.assertIsNone(fc2_lt_linear(*args))
_VALIDATED.clear()
extension.check.return_value = {"valid": True, "required_workspace_bytes": 0}
extension.run.side_effect = RuntimeError("run")
with (
patch.dict(os.environ, {"H3_NVFP4_FC2_LT_SPLITK1": "1"}, clear=True),
patch("h3_blackwell_runtime.fc2_lt._canonical_fc2_supported", return_value=True),
patch("h3_blackwell_runtime.fc2_lt._fc2_lt_extension_result", return_value=(extension, None)),
patch("h3_blackwell_runtime.fc2_lt.torch.zeros_like", return_value=MagicMock()),
patch("h3_blackwell_runtime.fc2_lt.torch.empty", return_value=MagicMock()),
):
self.assertIsNone(fc2_lt_linear(*args))
def test_strict_mode_raises_on_algo_check_and_execution_failures(self):
extension = MagicMock()
extension.build_info.return_value = {
"cuda_version": 13_000,
"cublas_version": 130_100,
"cuda_runtime_version": 13_000,
"cublaslt_runtime_version": 130_000,
}
linear = MagicMock()
linear.weight.shape = (5_376, 7_168)
gate_up = MagicMock()
gate_up.device.index = 0
qdata = MagicMock()
qdata.shape = (37_824, 7_168)
args = (linear, gate_up, MagicMock(), qdata, MagicMock())
environment = {
"H3_NVFP4_FC2_LT_SPLITK1": "1",
"H3_NVFP4_FC2_LT_STRICT": "1",
}
extension.check.return_value = {"valid": False, "required_workspace_bytes": 0}
with (
patch.dict(os.environ, environment, clear=True),
patch("h3_blackwell_runtime.fc2_lt._canonical_fc2_supported", return_value=True),
patch(
"h3_blackwell_runtime.fc2_lt._fc2_lt_extension_result",
return_value=(extension, None),
),
):
with self.assertRaisesRegex(RuntimeError, "algorithm check rejected"):
fc2_lt_linear(*args)
_VALIDATED.clear()
_fc2_lt_compatible_result.cache_clear()
extension.check.return_value = {"valid": True, "required_workspace_bytes": 0}
extension.run.side_effect = RuntimeError("run")
with (
patch.dict(os.environ, environment, clear=True),
patch("h3_blackwell_runtime.fc2_lt._canonical_fc2_supported", return_value=True),
patch(
"h3_blackwell_runtime.fc2_lt._fc2_lt_extension_result",
return_value=(extension, None),
),
patch("h3_blackwell_runtime.fc2_lt.torch.zeros_like", return_value=MagicMock()),
patch("h3_blackwell_runtime.fc2_lt.torch.empty", return_value=MagicMock()),
):
with self.assertRaisesRegex(RuntimeError, "execution failed"):
fc2_lt_linear(*args)
def test_forward_swiglu_uses_schedule_without_repacking(self):
linear = SimpleNamespace(
role="h3_mlp_fc2",
in_features=4,
out_features=3,
output_dtype=torch.bfloat16,
bias=None,
pre_quant_scale=None,
active_lora=None,
lora_strength=0.0,
full_precision_matrix_mult=False,
)
gate_up = torch.randn(1, 8, dtype=torch.bfloat16)
packed = (MagicMock(), MagicMock(), MagicMock())
expected = torch.randn(1, 3, dtype=torch.bfloat16)
with (
torch.inference_mode(),
patch.dict(os.environ, {"H3_NVFP4_FC2_LT_SPLITK1": "1"}, clear=True),
patch.object(torch.Tensor, "is_cuda", new_callable=unittest.mock.PropertyMock, return_value=True),
patch("h3_blackwell_runtime.nvfp4_quant.vortex_native_quantize_swiglu_nvfp4", return_value=packed) as quantize,
patch("h3_blackwell_runtime.nvfp4_quant.wrap_native_swiglu_nvfp4") as wrap,
patch("h3_blackwell_runtime.fc2_lt.fc2_lt_linear", return_value=expected) as scheduled,
):
actual = Nvfp4Linear.forward_swiglu(linear, gate_up)
self.assertTrue(torch.equal(actual, expected))
quantize.assert_called_once_with(gate_up)
scheduled.assert_called_once_with(linear, gate_up, *packed)
wrap.assert_not_called()
def test_forward_swiglu_reuses_native_bytes_on_fallback(self):
packed_weight = MagicMock()
linear = SimpleNamespace(
role="h3_mlp_fc2",
in_features=4,
out_features=3,
output_dtype=torch.bfloat16,
bias=None,
pre_quant_scale=None,
active_lora=None,
lora_strength=0.0,
full_precision_matrix_mult=False,
_packed_weight=lambda: packed_weight,
)
gate_up = torch.randn(1, 8, dtype=torch.bfloat16)
packed = (MagicMock(), MagicMock(), MagicMock())
wrapped = MagicMock()
expected = torch.randn(1, 3, dtype=torch.bfloat16)
with (
torch.inference_mode(),
patch.dict(os.environ, {"H3_NVFP4_FC2_LT_SPLITK1": "1"}, clear=True),
patch.object(torch.Tensor, "is_cuda", new_callable=unittest.mock.PropertyMock, return_value=True),
patch("h3_blackwell_runtime.nvfp4_quant.vortex_native_quantize_swiglu_nvfp4", return_value=packed) as quantize,
patch("h3_blackwell_runtime.nvfp4_quant.wrap_native_swiglu_nvfp4", return_value=wrapped) as wrap,
patch("h3_blackwell_runtime.fc2_lt.fc2_lt_linear", return_value=None),
patch("h3_blackwell_runtime.nvfp4.functional.linear", return_value=expected) as gemm,
):
actual = Nvfp4Linear.forward_swiglu(linear, gate_up)
self.assertTrue(torch.equal(actual, expected))
quantize.assert_called_once_with(gate_up)
wrap.assert_called_once_with(gate_up, packed)
gemm.assert_called_once_with(wrapped, packed_weight, None)
if __name__ == "__main__":
unittest.main()

View file

@ -27,7 +27,7 @@ from h3_blackwell_runtime.t2v import random_av_latents
ROOT = Path(__file__).resolve().parents[1]
SOURCE = ROOT / "research" / "fc2_nvfp4_scheduling" / "fc2_nvfp4_lt.cpp"
SOURCE = ROOT / "src" / "h3_blackwell_runtime" / "csrc" / "fc2_nvfp4_lt.cpp"
DEFAULT_BUDGETS = (0, 4 << 20, 8 << 20, 16 << 20, 32 << 20, 64 << 20)
DEFAULT_BLOCKS = (0, 24, 49)
ENV_PREFIXES = ("H3_", "COMFY_KITCHEN_", "CUDA_", "TORCH_")
@ -35,7 +35,15 @@ ENV_PREFIXES = ("H3_", "COMFY_KITCHEN_", "CUDA_", "TORCH_")
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--mode", choices=("compile", "characterize", "sweep", "selected", "profile", "block-gate", "trajectory"), default="characterize")
parser.add_argument(
"--mode",
choices=(
"compile", "characterize", "sweep", "selected", "profile",
"block-gate", "trajectory", "production-block-gate",
"production-trajectory", "shape-gate",
),
default="characterize",
)
parser.add_argument("--model-path", default="/models/minimax_h3_fl2va_pruned_nvfp4.safetensors")
parser.add_argument("--capture", type=Path, help="Directory containing input.pt, or an input .pt file")
parser.add_argument("--output", type=Path, default=Path("/output/h3-blackwell-runtime/benchmarks/fc2-nvfp4-scheduling.json"))
@ -48,6 +56,10 @@ def parse_args() -> argparse.Namespace:
parser.add_argument("--sampler-step", type=int, default=1)
parser.add_argument("--seed", type=int, default=440420)
parser.add_argument("--text-tokens", type=int, default=100)
parser.add_argument(
"--shape-text-tokens", type=int, nargs="+",
default=[1, 15, 32, 64, 99, 100, 128, 256, 512],
)
parser.add_argument("--blocks", type=int, nargs="+", default=list(DEFAULT_BLOCKS))
parser.add_argument("--probe-block", type=int, default=24)
parser.add_argument("--workspace-budgets", type=int, nargs="+", default=list(DEFAULT_BUDGETS))
@ -553,7 +565,109 @@ def block_gate(extension, model, block_inputs, block_outputs, gate_up, timesteps
return rows
def trajectory_gate(extension, checkpoint, model, config, args):
def production_block_gate(model, block_inputs, block_outputs, timesteps, rotation, segments, args):
from h3_blackwell_runtime.fc2_lt import fc2_lt_status
flag = "H3_NVFP4_FC2_LT_SPLITK1"
previous = os.environ.get(flag)
rows = []
def select(enabled: bool) -> None:
if enabled:
os.environ[flag] = "1"
else:
os.environ.pop(flag, None)
try:
for index in DEFAULT_BLOCKS:
block = model.backbone.blocks[index]
adaln_values = tuple(value.detach().clone() for value in model.backbone.adaln[index](timesteps))
def baseline():
select(False)
return block(block_inputs[index].detach().clone(), rotation, *adaln_values, segments)
def candidate():
select(True)
return block(block_inputs[index].detach().clone(), rotation, *adaln_values, segments)
before = fc2_lt_status()
timing = benchmark_pair(
baseline, candidate, args.rounds, args.warmup,
block_outputs[index].shape[0], block_outputs[index].shape[1], 1,
report_dense=False,
)
with torch.inference_mode():
baseline_value = baseline().detach().clone()
candidate_value = candidate().detach().clone()
after = fc2_lt_status()
dispatch_delta = {
name: after[name] - before[name]
for name in ("attempts", "successes", "fallbacks")
}
row = {
"block": index,
"production_method": "block.mlp.fc2.forward_swiglu",
"candidate_vs_baseline": compare(candidate_value, baseline_value),
"baseline_vs_traversal": compare(baseline_value, block_outputs[index]),
"candidate_vs_traversal": compare(candidate_value, block_outputs[index]),
"timing": timing,
"dispatch_delta": dispatch_delta,
}
if not all(
row[name]["bf16_exact"]
for name in ("candidate_vs_baseline", "baseline_vs_traversal", "candidate_vs_traversal")
):
raise RuntimeError(f"production FC2 schedule is not byte-exact in block {index}")
if dispatch_delta["successes"] == 0 or dispatch_delta["fallbacks"] != 0:
raise RuntimeError(f"production FC2 schedule did not dispatch cleanly in block {index}")
rows.append(row)
finally:
if previous is None:
os.environ.pop(flag, None)
else:
os.environ[flag] = previous
return rows
def shape_gate(extension, gate_up, fc2, config, args):
base_rows = gate_up.shape[0] - args.text_tokens
rows = []
for text_tokens in args.shape_text_tokens:
logical_rows = base_rows + text_tokens
if logical_rows <= gate_up.shape[0]:
actual_gate_up = gate_up[:logical_rows].contiguous()
else:
extra = logical_rows - gate_up.shape[0]
actual_gate_up = torch.cat((gate_up, gate_up[:extra]), dim=0).contiguous()
packed = packed_boundary(actual_gate_up, fc2)
run_candidate, _output, workspace = candidate_runner(
extension, packed, fc2, config, args.workspace_bytes,
)
timing = benchmark_pair(
comfy_packed_runner(packed, fc2, logical_rows), run_candidate,
args.rounds, args.warmup, logical_rows, fc2.out_features, fc2.in_features,
)
checked = dict(
extension.check(
packed[1], packed[2], fc2.weight, fc2.weight_scale, config,
)
)
row = {
"text_tokens": text_tokens,
"logical_rows": logical_rows,
"packed_rows": packed[1].shape[0],
"parity": timing["parity"],
"timing": timing,
"checked": checked,
"supplied_workspace_bytes": workspace.numel(),
}
row["passed"] = row["parity"]["bf16_exact"] and bool(checked.get("valid"))
rows.append(row)
return rows
def trajectory_gate(extension, checkpoint, model, config, args, *, production_dispatch=False):
packer = H3PromptPacker(checkpoint)
torch.manual_seed(args.seed)
video, audio, aligned_frames = random_av_latents(
@ -583,11 +697,31 @@ def trajectory_gate(extension, checkpoint, model, config, args):
return output[:actual_gate_up.shape[0], :fc2.out_features]
return types.MethodType(replacement, fc2)
candidates = [candidate_method(block.mlp.fc2) for block in model.backbone.blocks]
candidates = None if production_dispatch else [
candidate_method(block.mlp.fc2) for block in model.backbone.blocks
]
flag = "H3_NVFP4_FC2_LT_SPLITK1"
previous_flag = os.environ.get(flag)
if production_dispatch:
os.environ[flag] = "1"
from h3_blackwell_runtime.fc2_lt import prepare_fc2_lt
if not prepare_fc2_lt():
raise RuntimeError("production FC2 extension preparation failed")
if previous_flag is None:
os.environ.pop(flag, None)
else:
os.environ[flag] = previous_flag
def run(candidate: bool):
for index, block in enumerate(model.backbone.blocks):
block.mlp.fc2.forward_swiglu = candidates[index] if candidate else originals[index]
if production_dispatch:
if candidate:
os.environ[flag] = "1"
else:
os.environ.pop(flag, None)
else:
for index, block in enumerate(model.backbone.blocks):
block.mlp.fc2.forward_swiglu = candidates[index] if candidate else originals[index]
torch.cuda.synchronize()
started = time.perf_counter()
result = sample_video_res_multistep(
@ -607,10 +741,19 @@ def trajectory_gate(extension, checkpoint, model, config, args):
try:
with torch.inference_mode():
(reference_video, reference_audio), baseline_seconds = run(False)
if production_dispatch:
from h3_blackwell_runtime.fc2_lt import fc2_lt_status
dispatch_before = fc2_lt_status()
(candidate_video, candidate_audio), candidate_seconds = run(True)
if production_dispatch:
dispatch_after = fc2_lt_status()
finally:
for block, original in zip(model.backbone.blocks, originals, strict=True):
block.mlp.fc2.forward_swiglu = original
if previous_flag is None:
os.environ.pop(flag, None)
else:
os.environ[flag] = previous_flag
video_parity = compare(candidate_video, reference_video)
audio_parity = compare(candidate_audio, reference_audio)
@ -631,6 +774,17 @@ def trajectory_gate(extension, checkpoint, model, config, args):
"accepted_swiglu_producer_preserved": True,
"accepted_gate_and_residual_path_preserved": True,
}
if production_dispatch:
result["production_dispatch"] = True
result["dispatch_delta"] = {
name: dispatch_after[name] - dispatch_before[name]
for name in ("attempts", "successes", "fallbacks")
}
if result["dispatch_delta"]["successes"] == 0 or result["dispatch_delta"]["fallbacks"] != 0:
raise RuntimeError(
f"production FC2 schedule did not dispatch cleanly in trajectory: "
f"{result['dispatch_delta']}"
)
if not result["bf16_exact"]:
raise RuntimeError("FC2 library candidate trajectory is not byte-exact")
return result
@ -684,7 +838,11 @@ def main() -> None:
"explicit_split_k_checks": explicit,
}
if args.mode in {"characterize", "sweep", "selected", "profile", "block-gate", "trajectory"}:
if args.mode in {
"characterize", "sweep", "selected", "profile", "block-gate",
"trajectory", "production-block-gate", "production-trajectory",
"shape-gate",
}:
config = resolve_candidate(args, enumerated, explicit)
result["selected"] = config
if args.mode == "characterize":
@ -712,8 +870,20 @@ def main() -> None:
result["profile"] = profile_one(extension, packed, fc2, config, gate_ups[probe].shape[0], args)
elif args.mode == "block-gate":
result["block_gate"] = block_gate(extension, model, block_inputs, block_outputs, gate_ups, timesteps, rotation, segments, config, args)
elif args.mode == "production-block-gate":
result["production_block_gate"] = production_block_gate(
model, block_inputs, block_outputs, timesteps, rotation, segments, args,
)
elif args.mode == "shape-gate":
result["shape_gate"] = shape_gate(
extension, gate_ups[probe], fc2, config, args,
)
elif args.mode == "trajectory":
result["trajectory"] = trajectory_gate(extension, checkpoint, model, config, args)
elif args.mode == "production-trajectory":
result["trajectory"] = trajectory_gate(
extension, checkpoint, model, config, args, production_dispatch=True,
)
result["errors_and_unsupported"] = errors + [{
"feature": "Stream-K",