hip-quant 2.2.2__tar.gz → 2.2.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. {hip_quant-2.2.2 → hip_quant-2.2.3}/MANIFEST.in +2 -0
  2. {hip_quant-2.2.2/hip_quant.egg-info → hip_quant-2.2.3}/PKG-INFO +82 -11
  3. {hip_quant-2.2.2 → hip_quant-2.2.3}/README.md +81 -10
  4. hip_quant-2.2.3/_C.cp312-win_amd64.pyd +4 -0
  5. {hip_quant-2.2.2 → hip_quant-2.2.3}/__init__.py +1 -1
  6. {hip_quant-2.2.2 → hip_quant-2.2.3}/gguf.py +4 -0
  7. {hip_quant-2.2.2 → hip_quant-2.2.3/hip_quant.egg-info}/PKG-INFO +82 -11
  8. {hip_quant-2.2.2 → hip_quant-2.2.3}/hip_quant.egg-info/SOURCES.txt +27 -1
  9. {hip_quant-2.2.2 → hip_quant-2.2.3}/pyproject.toml +3 -1
  10. {hip_quant-2.2.2 → hip_quant-2.2.3}/setup.py +2 -0
  11. {hip_quant-2.2.2 → hip_quant-2.2.3}/setup_torch.py +7 -0
  12. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_wave_attn_decode_hybrid.py +47 -0
  13. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/torch/test_wave_attn_backward_math.py +143 -1
  14. hip_quant-2.2.3/tests/torch/test_wave_attn_f16.py +99 -0
  15. hip_quant-2.2.3/tests/torch/test_wave_attn_f16_extreme.py +549 -0
  16. hip_quant-2.2.3/tests/torch/test_wave_attn_train_bf16.py +101 -0
  17. hip_quant-2.2.3/tests/torch/test_wave_helpers_cpu.py +48 -0
  18. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_api.py +209 -4
  19. hip_quant-2.2.3/torch_ext/decode_quant_kernels.hip +240 -0
  20. hip_quant-2.2.3/torch_ext/int4_wmma_kernels.hip +168 -0
  21. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/kv_iu4_kernels.hip +158 -14
  22. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/pytorch_bindings.cpp +1028 -26
  23. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/ssm_kernels.hip +89 -18
  24. hip_quant-2.2.3/torch_ext/ternary_gemv_kernels.hip +567 -0
  25. hip_quant-2.2.3/torch_ext/w4a16_gemv_kernels.hip +709 -0
  26. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/wave_attn.hip +6 -6
  27. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/wave_attn_backward.hip +91 -30
  28. hip_quant-2.2.3/torch_ext/wave_attn_backward_f16.hip +680 -0
  29. hip_quant-2.2.3/torch_ext/wave_attn_decode.hip +935 -0
  30. hip_quant-2.2.3/torch_ext/wave_attn_f16.hip +638 -0
  31. hip_quant-2.2.3/torch_ext/wht_kernels.hip +200 -0
  32. hip_quant-2.2.3/wave_attn_train_strided_triton.py +259 -0
  33. hip_quant-2.2.3/wave_attn_train_triton.py +206 -0
  34. {hip_quant-2.2.2 → hip_quant-2.2.3}/wave_helpers.py +57 -8
  35. hip_quant-2.2.2/_C.cp312-win_amd64.pyd +0 -0
  36. hip_quant-2.2.2/torch_ext/wave_attn_decode.hip +0 -288
  37. {hip_quant-2.2.2 → hip_quant-2.2.3}/DOCUMENTATION.md +0 -0
  38. {hip_quant-2.2.2 → hip_quant-2.2.3}/LICENSE +0 -0
  39. {hip_quant-2.2.2 → hip_quant-2.2.3}/__main__.py +0 -0
  40. {hip_quant-2.2.2 → hip_quant-2.2.3}/bench_mxfp8.py +0 -0
  41. {hip_quant-2.2.2 → hip_quant-2.2.3}/bench_wave_attn_inference.py +0 -0
  42. {hip_quant-2.2.2 → hip_quant-2.2.3}/build.ps1 +0 -0
  43. {hip_quant-2.2.2 → hip_quant-2.2.3}/build.sh +0 -0
  44. {hip_quant-2.2.2 → hip_quant-2.2.3}/cdna_compat.py +0 -0
  45. {hip_quant-2.2.2 → hip_quant-2.2.3}/codebooks/iq1_s.bin +0 -0
  46. {hip_quant-2.2.2 → hip_quant-2.2.3}/codebooks/iq2_s.bin +0 -0
  47. {hip_quant-2.2.2 → hip_quant-2.2.3}/codebooks/iq2_xs.bin +0 -0
  48. {hip_quant-2.2.2 → hip_quant-2.2.3}/codebooks/iq2_xxs.bin +0 -0
  49. {hip_quant-2.2.2 → hip_quant-2.2.3}/codebooks/iq3_s.bin +0 -0
  50. {hip_quant-2.2.2 → hip_quant-2.2.3}/codebooks/iq3_xxs.bin +0 -0
  51. {hip_quant-2.2.2 → hip_quant-2.2.3}/demo.py +0 -0
  52. {hip_quant-2.2.2 → hip_quant-2.2.3}/device_info.py +0 -0
  53. {hip_quant-2.2.2 → hip_quant-2.2.3}/diagnose_fp8_crash.py +0 -0
  54. {hip_quant-2.2.2 → hip_quant-2.2.3}/e2e_iq2s_iq1m.py +0 -0
  55. {hip_quant-2.2.2 → hip_quant-2.2.3}/get_hf_tensors.py +0 -0
  56. {hip_quant-2.2.2 → hip_quant-2.2.3}/gguf_loader.py +0 -0
  57. {hip_quant-2.2.2 → hip_quant-2.2.3}/hip_iquant_util.h +0 -0
  58. {hip_quant-2.2.2 → hip_quant-2.2.3}/hip_quant.egg-info/dependency_links.txt +0 -0
  59. {hip_quant-2.2.2 → hip_quant-2.2.3}/hip_quant.egg-info/entry_points.txt +0 -0
  60. {hip_quant-2.2.2 → hip_quant-2.2.3}/hip_quant.egg-info/not-zip-safe +0 -0
  61. {hip_quant-2.2.2 → hip_quant-2.2.3}/hip_quant.egg-info/requires.txt +0 -0
  62. {hip_quant-2.2.2 → hip_quant-2.2.3}/hip_quant.egg-info/top_level.txt +0 -0
  63. {hip_quant-2.2.2 → hip_quant-2.2.3}/hip_quant_types.h +0 -0
  64. {hip_quant-2.2.2 → hip_quant-2.2.3}/hip_quant_util.h +0 -0
  65. {hip_quant-2.2.2 → hip_quant-2.2.3}/hip_quantize.cpp +0 -0
  66. {hip_quant-2.2.2 → hip_quant-2.2.3}/hip_quantize.dll +0 -0
  67. {hip_quant-2.2.2 → hip_quant-2.2.3}/hip_quantize_rocm721.dll +0 -0
  68. {hip_quant-2.2.2 → hip_quant-2.2.3}/hq2/__init__.py +0 -0
  69. {hip_quant-2.2.2 → hip_quant-2.2.3}/hq2/__main__.py +0 -0
  70. {hip_quant-2.2.2 → hip_quant-2.2.3}/hq2/analyzer.py +0 -0
  71. {hip_quant-2.2.2 → hip_quant-2.2.3}/hq2/api.py +0 -0
  72. {hip_quant-2.2.2 → hip_quant-2.2.3}/hq2/archive.py +0 -0
  73. {hip_quant-2.2.2 → hip_quant-2.2.3}/hq2/backends.py +0 -0
  74. {hip_quant-2.2.2 → hip_quant-2.2.3}/hq2/format.py +0 -0
  75. {hip_quant-2.2.2 → hip_quant-2.2.3}/hq2/hq3.py +0 -0
  76. {hip_quant-2.2.2 → hip_quant-2.2.3}/hq2/hq8.py +0 -0
  77. {hip_quant-2.2.2 → hip_quant-2.2.3}/hq2/mixed_policy.py +0 -0
  78. {hip_quant-2.2.2 → hip_quant-2.2.3}/hq2/raw.py +0 -0
  79. {hip_quant-2.2.2 → hip_quant-2.2.3}/hq2/safetensors_numpy.py +0 -0
  80. {hip_quant-2.2.2 → hip_quant-2.2.3}/hq2/sensitivity.py +0 -0
  81. {hip_quant-2.2.2 → hip_quant-2.2.3}/hq2/torch_inference.py +0 -0
  82. {hip_quant-2.2.2 → hip_quant-2.2.3}/hq2/transformers_loader.py +0 -0
  83. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/dequant_to_fp8.cu +0 -0
  84. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/direct_fp8_quant.cu +0 -0
  85. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/fp8_expand.cu +0 -0
  86. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/fp8_gemm_test.cu +0 -0
  87. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_aq2.cu +0 -0
  88. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_bf16.cu +0 -0
  89. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_f8_e4m3.cu +0 -0
  90. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_f8_e5m2.cu +0 -0
  91. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_hq2.cu +0 -0
  92. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_iq1_m.cu +0 -0
  93. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_iq1_s.cu +0 -0
  94. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_iq2_s.cu +0 -0
  95. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_iq2_xs.cu +0 -0
  96. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_iq2_xxs.cu +0 -0
  97. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_iq3_s.cu +0 -0
  98. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_iq3_xxs.cu +0 -0
  99. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_iq4_nl.cu +0 -0
  100. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_iq4_xs.cu +0 -0
  101. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_q1_0.cu +0 -0
  102. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_q2_0.cu +0 -0
  103. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_q2_K.cu +0 -0
  104. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_q3_K.cu +0 -0
  105. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_q4_0.cu +0 -0
  106. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_q4_1.cu +0 -0
  107. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_q4_K.cu +0 -0
  108. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_q5_0.cu +0 -0
  109. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_q5_1.cu +0 -0
  110. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_q5_K.cu +0 -0
  111. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_q6_K.cu +0 -0
  112. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_q8_0.cu +0 -0
  113. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_q8_1.cu +0 -0
  114. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_q8_K.cu +0 -0
  115. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_tq1_0.cu +0 -0
  116. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/quant_tq2_0.cu +0 -0
  117. {hip_quant-2.2.2 → hip_quant-2.2.3}/kernels/wmma_diag.cu +0 -0
  118. {hip_quant-2.2.2 → hip_quant-2.2.3}/setup.cfg +0 -0
  119. {hip_quant-2.2.2 → hip_quant-2.2.3}/smi.py +0 -0
  120. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/__init__.py +0 -0
  121. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/bench_attn_compare.py +0 -0
  122. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/bench_iq2s_variants.py +0 -0
  123. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/bench_wave_prefill.py +0 -0
  124. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/debug_conv1d.py +0 -0
  125. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_aq2.py +0 -0
  126. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_bf16_numpy.py +0 -0
  127. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_compat.py +0 -0
  128. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_dequant_fp8.py +0 -0
  129. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_direct_fp8_quant.py +0 -0
  130. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_ffn_layer.py +0 -0
  131. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_fused_ssm_prefill.py +0 -0
  132. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_gemv_kquants.py +0 -0
  133. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_hq2.py +0 -0
  134. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_hq2_portable.py +0 -0
  135. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_hq8_g128.py +0 -0
  136. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_iq2s_iq1m_byte_exact.py +0 -0
  137. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_iquant_parallel.py +0 -0
  138. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_lazy_torch_import.py +0 -0
  139. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_mixed_policy.py +0 -0
  140. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_mixed_sensitivity.py +0 -0
  141. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_mxfp4_compat.py +0 -0
  142. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_mxfp4_native_contract.py +0 -0
  143. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_mxfp8_numerical.py +0 -0
  144. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_patch_hq_mixed_archive.py +0 -0
  145. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_pipeline.py +0 -0
  146. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_prefill_with_lse.py +0 -0
  147. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_q_to_fp8_gpu.py +0 -0
  148. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_qol.py +0 -0
  149. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_safetensors_numpy.py +0 -0
  150. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_v8.py +0 -0
  151. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_wave_prefill_gqa.py +0 -0
  152. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_wmma_diag.py +0 -0
  153. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/test_wmma_layout.py +0 -0
  154. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/torch/bench_compare.py +0 -0
  155. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/torch/bench_fp8.py +0 -0
  156. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/torch/conftest.py +0 -0
  157. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/torch/test_fp8.py +0 -0
  158. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/torch/test_fp8_v2.py +0 -0
  159. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/torch/test_hip_graph.py +0 -0
  160. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/torch/test_mxfp4_native_contract_torch.py +0 -0
  161. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/torch/test_mxfp4_to_fp8_torch.py +0 -0
  162. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/torch/test_mxfp8_torch.py +0 -0
  163. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/torch/test_q_to_fp8_torch.py +0 -0
  164. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/torch/test_quant_transpose.py +0 -0
  165. {hip_quant-2.2.2 → hip_quant-2.2.3}/tests/verify_fused_fp8_linear.py +0 -0
  166. {hip_quant-2.2.2 → hip_quant-2.2.3}/tools/.gpu-smi-version +0 -0
  167. {hip_quant-2.2.2 → hip_quant-2.2.3}/tools/fetch_gpu_smi.py +0 -0
  168. {hip_quant-2.2.2 → hip_quant-2.2.3}/tools/gpu-smi.exe +0 -0
  169. {hip_quant-2.2.2 → hip_quant-2.2.3}/tools/mlp_codec/analyze.py +0 -0
  170. {hip_quant-2.2.2 → hip_quant-2.2.3}/tools/mlp_codec/clean_wikitext.py +0 -0
  171. {hip_quant-2.2.2 → hip_quant-2.2.3}/tools/mlp_codec/collect_hessians.py +0 -0
  172. {hip_quant-2.2.2 → hip_quant-2.2.3}/tools/mlp_codec/hq2_bridge.py +0 -0
  173. {hip_quant-2.2.2 → hip_quant-2.2.3}/tools/mlp_codec/hq2v.py +0 -0
  174. {hip_quant-2.2.2 → hip_quant-2.2.3}/tools/mlp_codec/ldlq.py +0 -0
  175. {hip_quant-2.2.2 → hip_quant-2.2.3}/tools/mlp_codec/ledger.py +0 -0
  176. {hip_quant-2.2.2 → hip_quant-2.2.3}/tools/mlp_codec/run_ladder.py +0 -0
  177. {hip_quant-2.2.2 → hip_quant-2.2.3}/tools/mlp_codec/safe_run.py +0 -0
  178. {hip_quant-2.2.2 → hip_quant-2.2.3}/tools/mlp_codec/validate_hessians.py +0 -0
  179. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/current_stream.hip +0 -0
  180. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/dequant_q_to_fp16.hip +0 -0
  181. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/fp8_linear_kernels.hip +0 -0
  182. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/fp8_linear_kernels_v2.hip +0 -0
  183. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/fp8_quant_kernels.hip +0 -0
  184. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/gemv_q_kernels.hip +0 -0
  185. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/hq2_linear_kernels.hip +0 -0
  186. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/hq3_linear_kernels.hip +0 -0
  187. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/hq8_g128_linear_kernels.hip +0 -0
  188. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/iq_grid_tables.h +0 -0
  189. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/mxfp4_to_fp8_kernels.hip +0 -0
  190. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/mxfp8_kernels.hip +0 -0
  191. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/pytorch_bindings_hip.cpp +0 -0
  192. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/q_to_fp8_kernels.hip +0 -0
  193. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/wave_attn_common.h +0 -0
  194. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/wave_attn_diag.hip +0 -0
  195. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/wave_attn_long.hip +0 -0
  196. {hip_quant-2.2.2 → hip_quant-2.2.3}/torch_ext/wave_attn_prefill.hip +0 -0
@@ -13,6 +13,8 @@ recursive-include torch_ext *.cpp *.hip *.h
13
13
  recursive-include tests *.py
14
14
  recursive-include codebooks *.bin
15
15
  include torch_api.py
16
+ include wave_attn_train_triton.py
17
+ include wave_attn_train_strided_triton.py
16
18
  include wave_helpers.py
17
19
  include smi.py
18
20
  include gguf.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hip-quant
3
- Version: 2.2.2
3
+ Version: 2.2.3
4
4
  Summary: High-performance GPU tensor quantization and inference engine for AMD ROCm. Native AOT GEMV (K-Quants & I-Quants), State Space Model (SSM/DeltaNet) kernels, FP8 WMMA WaveAttention, and portable HIP C++ kernels for RDNA4, RDNA3, and CDNA.
5
5
  Author-email: Thenukegun10x <conormorris84@gmail.com>
6
6
  License: Apache License
@@ -239,6 +239,34 @@ Dynamic: license-file
239
239
 
240
240
  `hip-quant` is a standalone Python library and highly optimized HIP C++ backend for tensor quantization and accelerated LLM inference on AMD GPUs with zero CPU round-trips.
241
241
 
242
+ > ⚠️ **Numerical / experimental status — WaveAttention training kernels.**
243
+ > The WaveAttention **training** paths are experimental. The native FP8 path
244
+ > (`precision="native"`, the default) is an inference-grade kernel: against a
245
+ > BF16 MATH-SDPA reference its `dQ`/`dK` relative L2 is about **8% at input
246
+ > scale 1 and ~58% at scale 5**, so it is *not* suitable for training as-is.
247
+ > The `precision="fp16"` native WMMA kernels (new in 2.2.3) are the accurate
248
+ > choice: against an fp32 SDPA reference the forward/backward relative L2 is
249
+ > ~2e-4 / ~3e-4 at the tested shapes and input scales, and an adversarial
250
+ > NaN/Inf + extreme-range harness passes clean. The `precision="bf16"` Triton
251
+ > kernels are kept as a fallback. **Full-model convergence and end-to-end speed
252
+ > remain unverified** (a 3,000-update PlantUnified continuation was finite,
253
+ > without EMA/validation). A CPU float64 operand study
254
+ > (`benchmarks/wave_attn_train_results.md`) found that no FP8 operand mixture —
255
+ > including Hadamard-rotated, block-scaled FP8 — reaches a sub-1% training
256
+ > target; f16 WMMA operands are the accurate choice. **Validate accuracy and
257
+ > convergence on your own workload before training with any of these paths.**
258
+
259
+ ## 🌟 What's New in 2.2.3
260
+
261
+ > **2.2.3.post215** is the same release rebuilt against PyTorch 2.15 (TheRock / ROCm 7.14).
262
+
263
+ - **🌊 Native FP16 WMMA training attention (`gfx1201`).** `wave_attn(..., precision="fp16")` now runs a purpose-built FP16 flash-attention **forward and backward** on `v_wmma_f32_16x16x16_f16` — no Triton, and no SDPA recomputation for the backward. `dQ`/`dK`/`dV` are computed on-device with a FlashAttention-2 preprocess pass for `D_i = Σ_d dO_id·O_id`. Against the AOTriton SDPA baseline (`F.scaled_dot_product_attention`, flash backend) at `B1 H16`, the **forward is faster on all eight measured shapes** (1.35–2.13×; 60.9–68.4 vs 44.8–50.9 TFLOP/s at `S4096`). The **backward is still behind AOTriton** (1.47–2.06× slower; 14–22 vs 26–38 TFLOP/s): its `dK`/`dV` block needs one wave per 16-key sub-tile and ~53 KB of shared memory, which caps it at four waves per CTA and one CTA per CU.
264
+ - **🐛 Three training-correctness bugs found and fixed**, by a new adversarial harness (`tests/torch/test_wave_attn_f16_extreme.py`: ~70 hand-built cases plus a log-uniform fuzz against an fp64 reference):
265
+ - **`dS` fp16 overflow → NaN.** `|dS| ≈ 3.41·|V|·|dO|` at `D=128`, so perfectly valid fp16 inputs (`V=65504`, `dO=1`) overflowed the `dS` store and produced NaN gradients. A per-`(b,h)` scale from the preprocess pass now bounds `dS`, and the output is divided back out; the `min(1, …)` cap keeps ordinary inputs bit-identical to the unscaled kernel.
266
+ - **Causal mask mismatch when `Seq_K > Seq_Q`.** The FP16 forward carried a bottom-right offset while the backward — and PyTorch's `is_causal` — are strictly top-left. The offset is gone, so forward and backward now agree.
267
+ - **`LSE` log-term loss.** Storing `row max + log(row sum)` as a single fp32 rounded the log term away once the max exceeded ~4e7, making `dV` exactly **128× too large** and turning a cancellation residual into a spurious `dQ` of 1.44e7 where the true value is exactly 0. `LSE` is now two fp32 per row, subtracted separately.
268
+ - **🛡️ The forward can no longer overflow fp32.** Scores stay in the raw WMMA domain and `softmax_scale` is applied *inside* the exponent as `(raw − raw)·|scale|`. Forming `sacc·scale` was the forward's only fp32 overflow site (`|sacc| ≤ D·65504² = 5.5e11`, so `scale > 6.19e26` NaNs everything downstream) — and PyTorch's own fp32 SDPA and a textbook fp32 softmax **do** NaN at exactly that threshold. The native kernel now matches fp64 exactly there, while still agreeing with SDPA to ~2e-4 in the normal range. A negative `softmax_scale` (softmax of `−s`) is normalised out, so it is unaffected.
269
+
242
270
  ## 🌟 What's New in 2.2.2
243
271
 
244
272
  > **2.2.2.post215** is the same release rebuilt against PyTorch 2.15 (TheRock / ROCm 7.14).
@@ -310,7 +338,15 @@ q = torch.randn(4, 8, 256, 64, device="cuda")
310
338
  k = torch.randn(4, 8, 256, 64, device="cuda")
311
339
  v = torch.randn(4, 8, 256, 64, device="cuda")
312
340
 
313
- out = hip_quant.wave_attn(q, k, v) # FP8 WMMA, 3-8x faster than SDPA
341
+ out = hip_quant.wave_attn(q, k, v) # native FP8 WMMA (inference-grade)
342
+ # Native FP16 WMMA training kernels on gfx1201 (forward + backward, no Triton):
343
+ qh, kh, vh = q.half(), k.half(), v.half()
344
+ out_fp16 = hip_quant.wave_attn(qh, kh, vh, precision="fp16")
345
+ # BF16 Triton fallback (requires ROCm Triton):
346
+ qbf, kbf, vbf = q.bfloat16(), k.bfloat16(), v.bfloat16()
347
+ out_bf16 = hip_quant.wave_attn(qbf, kbf, vbf, precision="bf16")
348
+ # Or defer to PyTorch SDPA entirely:
349
+ out_precise = hip_quant.wave_attn(q, k, v, precision="sdpa")
314
350
  ```
315
351
 
316
352
  **Key features:**
@@ -322,7 +358,7 @@ out = hip_quant.wave_attn(q, k, v) # FP8 WMMA, 3-8x faster than SDPA
322
358
  - Multi-split parallelism for low-occupancy configs
323
359
  - Native INT4 WMMA path (`wave_attn_int4`) — Q/K 4-bit, V FP8, LUT unpack (new in 1.3.0)
324
360
 
325
- **Performance — RX 9070 XT `gfx1201`, `ROCm 7.2.1` + `torch 2.9.1+rocm7.2.1`, `D=128` (measured `bench_attn.py` vs `F.scaled_dot_product_attention`/AOTriton):**
361
+ **Historical performance — RX 9070 XT `gfx1201`, `ROCm 7.2.1` + `torch 2.9.1+rocm7.2.1`, `D=128` (measured `bench_attn.py` against its AOTriton SDPA path):**
326
362
 
327
363
  | Config (B,H,S,D) | Causal | `wave` fwd | `SDPA` fwd | fwd speedup | `wave` bwd | `SDPA` bwd | bwd speedup |
328
364
  |---|:---:|---|---|---|---|---|---|
@@ -334,9 +370,44 @@ out = hip_quant.wave_attn(q, k, v) # FP8 WMMA, 3-8x faster than SDPA
334
370
  | 1,32,256,128 | Y | 0.139 ms | 0.370 ms | **2.66×** | 0.298 ms | 1.158 ms | **3.89×** |
335
371
  | 1,32,1024,128 | Y | 0.792 ms | 4.422 ms | **5.59×** | 2.878 ms | 10.632 ms | **3.69×** |
336
372
 
337
- Accuracy: FP8 `cos ~0.9986-0.999` vs FP32 reference, backward `dQ 0.9981 / dK 0.9986 / dV 0.9999`, stable across `S`.
338
-
339
- > **Why not FA3?** FlashAttention-3 is `Hopper` (`sm90`) CUDA-only — no ROCm/HIP port and no `gfx12` codegen. The fair ROCm baseline is `PyTorch SDPA` which on ROCm routes to `AOTriton` (`Efficient Attention`). `wave_attn` beats that path by specializing for `gfx1200/1201` `WMMA` directly.
373
+ The table describes that benchmark's backend and shapes; it is not a current
374
+ speed claim for every SDPA backend or training shape. On the same RX 9070 XT
375
+ with `B=6,H=12,S=789,D=64` BF16 inputs, the full native FP8 training API
376
+ takes **1.87 ms** forward plus backward, while `precision="sdpa"` takes
377
+ **1.03 ms**. Against BF16 MATH SDPA, native dQ/dK relative L2 is about 8%
378
+ at input scale 1 and 58% at scale 5; the SDPA precision mode is below 1%.
379
+ See `benchmarks/wave_attn_train_results.md` for methods and all metrics.
380
+
381
+ > The native FP8 path remains available with `precision="native"` (the default),
382
+ > including for prequantized `uint8` inputs. The SDPA precision mode is for
383
+ > floating-point training inputs and returns a float32 output.
384
+
385
+ **BF16 training mode (experimental):** `precision="bf16"` uses Triton kernels
386
+ that compile to gfx1201 `v_wmma_f32_16x16x16_bf16` instructions. It accepts
387
+ contiguous, equal-shaped BF16 Q/K/V with head dimension 64 or 128; the output
388
+ and input gradients are BF16. A separate FP32 output is saved for backward so
389
+ large-score gradients retain accuracy. The full public forward/backward call
390
+ beats default BF16 SDPA on the RX 9070 XT at `B=6,H=12,S=789`: 0.75 vs 1.02 ms
391
+ for D=64 noncausal, 0.35 vs 0.98 ms causal; 2.24 vs 2.85 ms for D=128
392
+ noncausal, 1.41 vs 1.96 ms causal (100 GPU-event repeats, medians of three
393
+ rounds). Output and gradient relative L2 against FP32 MATH stay below 0.26%
394
+ at input scales 1 and 5. Small attention calls can be slower than SDPA, so
395
+ select this mode for measured training workloads. See
396
+ `benchmarks/check_wave_attn_train_gate.py`,
397
+ `benchmarks/check_plant_wave_continuation.py`, and
398
+ `benchmarks/wave_attn_train_results.md` for the checks.
399
+
400
+ To route timm's SDPA calls through the BF16 path, set
401
+ `HIP_QUANT_WAVE_ATTN_PRECISION=bf16` before calling `patch_sdpa()` (or before a
402
+ trainer's `--wave-attention` flag). The helper makes timm's transposed Q/K/V
403
+ views contiguous and returns BF16 outputs; unsupported attention shapes still
404
+ use SDPA. A BF16 kernel error propagates instead of silently falling back.
405
+ From a real PlantUnified checkpoint at step 131,780, the BF16 path completed
406
+ 3,000 more training updates with finite loss and gradients, using 24 attention
407
+ calls per update across the 12 DINOv3 blocks and their checkpoint recomputations.
408
+ The bounded run did not perform EMA or validation; the eight-step matched A/B
409
+ ended at loss 7.7051 (BF16 WaveAttention) versus 7.7122 (BF16 SDPA). A
410
+ full-model speed win and full-epoch convergence remain unverified.
340
411
 
341
412
  ## HQ2 / HQ3 — experimental learned-codebook formats
342
413
 
@@ -574,7 +645,7 @@ pip install hip-quant
574
645
  pip install "hip-quant[torch]"
575
646
 
576
647
  # Or a local wheel
577
- pip install dist/hip_quant-2.2.0-cp312-cp312-win_amd64.whl
648
+ pip install dist/hip_quant-2.2.3-cp312-cp312-win_amd64.whl
578
649
  ```
579
650
 
580
651
  Two wheels are published per release, one per PyTorch ABI. Install the one that
@@ -582,11 +653,11 @@ matches your PyTorch, so the extension loads without an ABI mismatch:
582
653
 
583
654
  | Wheel | PyTorch | ROCm |
584
655
  |---|---|---|
585
- | `hip-quant==2.2.2` | 2.9.x | ROCm 7.2.1 |
586
- | `hip-quant==2.2.2.post215` | 2.15 / TheRock | ROCm 7.14 |
656
+ | `hip-quant==2.2.3` | 2.9.x | ROCm 7.2.1 |
657
+ | `hip-quant==2.2.3.post215` | 2.15 / TheRock | ROCm 7.14 |
587
658
 
588
659
  ```powershell
589
- pip install "hip-quant==2.2.2.post215" # PyTorch 2.15 / TheRock
660
+ pip install "hip-quant==2.2.3.post215" # PyTorch 2.15 / TheRock
590
661
  ```
591
662
 
592
663
  #### Custom PyTorch 2.15 (self-hosted wheels)
@@ -596,7 +667,7 @@ Its wheels live in a public Backblaze B2 bucket; point pip at the index page
596
667
  with `--find-links`:
597
668
 
598
669
  ```powershell
599
- pip install "hip-quant==2.2.2.post215" `
670
+ pip install "hip-quant==2.2.3.post215" `
600
671
  --find-links https://dl.hipquant.download/file/Torchs/torch_index.html
601
672
  ```
602
673
 
@@ -14,6 +14,34 @@
14
14
 
15
15
  `hip-quant` is a standalone Python library and highly optimized HIP C++ backend for tensor quantization and accelerated LLM inference on AMD GPUs with zero CPU round-trips.
16
16
 
17
+ > ⚠️ **Numerical / experimental status — WaveAttention training kernels.**
18
+ > The WaveAttention **training** paths are experimental. The native FP8 path
19
+ > (`precision="native"`, the default) is an inference-grade kernel: against a
20
+ > BF16 MATH-SDPA reference its `dQ`/`dK` relative L2 is about **8% at input
21
+ > scale 1 and ~58% at scale 5**, so it is *not* suitable for training as-is.
22
+ > The `precision="fp16"` native WMMA kernels (new in 2.2.3) are the accurate
23
+ > choice: against an fp32 SDPA reference the forward/backward relative L2 is
24
+ > ~2e-4 / ~3e-4 at the tested shapes and input scales, and an adversarial
25
+ > NaN/Inf + extreme-range harness passes clean. The `precision="bf16"` Triton
26
+ > kernels are kept as a fallback. **Full-model convergence and end-to-end speed
27
+ > remain unverified** (a 3,000-update PlantUnified continuation was finite,
28
+ > without EMA/validation). A CPU float64 operand study
29
+ > (`benchmarks/wave_attn_train_results.md`) found that no FP8 operand mixture —
30
+ > including Hadamard-rotated, block-scaled FP8 — reaches a sub-1% training
31
+ > target; f16 WMMA operands are the accurate choice. **Validate accuracy and
32
+ > convergence on your own workload before training with any of these paths.**
33
+
34
+ ## 🌟 What's New in 2.2.3
35
+
36
+ > **2.2.3.post215** is the same release rebuilt against PyTorch 2.15 (TheRock / ROCm 7.14).
37
+
38
+ - **🌊 Native FP16 WMMA training attention (`gfx1201`).** `wave_attn(..., precision="fp16")` now runs a purpose-built FP16 flash-attention **forward and backward** on `v_wmma_f32_16x16x16_f16` — no Triton, and no SDPA recomputation for the backward. `dQ`/`dK`/`dV` are computed on-device with a FlashAttention-2 preprocess pass for `D_i = Σ_d dO_id·O_id`. Against the AOTriton SDPA baseline (`F.scaled_dot_product_attention`, flash backend) at `B1 H16`, the **forward is faster on all eight measured shapes** (1.35–2.13×; 60.9–68.4 vs 44.8–50.9 TFLOP/s at `S4096`). The **backward is still behind AOTriton** (1.47–2.06× slower; 14–22 vs 26–38 TFLOP/s): its `dK`/`dV` block needs one wave per 16-key sub-tile and ~53 KB of shared memory, which caps it at four waves per CTA and one CTA per CU.
39
+ - **🐛 Three training-correctness bugs found and fixed**, by a new adversarial harness (`tests/torch/test_wave_attn_f16_extreme.py`: ~70 hand-built cases plus a log-uniform fuzz against an fp64 reference):
40
+ - **`dS` fp16 overflow → NaN.** `|dS| ≈ 3.41·|V|·|dO|` at `D=128`, so perfectly valid fp16 inputs (`V=65504`, `dO=1`) overflowed the `dS` store and produced NaN gradients. A per-`(b,h)` scale from the preprocess pass now bounds `dS`, and the output is divided back out; the `min(1, …)` cap keeps ordinary inputs bit-identical to the unscaled kernel.
41
+ - **Causal mask mismatch when `Seq_K > Seq_Q`.** The FP16 forward carried a bottom-right offset while the backward — and PyTorch's `is_causal` — are strictly top-left. The offset is gone, so forward and backward now agree.
42
+ - **`LSE` log-term loss.** Storing `row max + log(row sum)` as a single fp32 rounded the log term away once the max exceeded ~4e7, making `dV` exactly **128× too large** and turning a cancellation residual into a spurious `dQ` of 1.44e7 where the true value is exactly 0. `LSE` is now two fp32 per row, subtracted separately.
43
+ - **🛡️ The forward can no longer overflow fp32.** Scores stay in the raw WMMA domain and `softmax_scale` is applied *inside* the exponent as `(raw − raw)·|scale|`. Forming `sacc·scale` was the forward's only fp32 overflow site (`|sacc| ≤ D·65504² = 5.5e11`, so `scale > 6.19e26` NaNs everything downstream) — and PyTorch's own fp32 SDPA and a textbook fp32 softmax **do** NaN at exactly that threshold. The native kernel now matches fp64 exactly there, while still agreeing with SDPA to ~2e-4 in the normal range. A negative `softmax_scale` (softmax of `−s`) is normalised out, so it is unaffected.
44
+
17
45
  ## 🌟 What's New in 2.2.2
18
46
 
19
47
  > **2.2.2.post215** is the same release rebuilt against PyTorch 2.15 (TheRock / ROCm 7.14).
@@ -85,7 +113,15 @@ q = torch.randn(4, 8, 256, 64, device="cuda")
85
113
  k = torch.randn(4, 8, 256, 64, device="cuda")
86
114
  v = torch.randn(4, 8, 256, 64, device="cuda")
87
115
 
88
- out = hip_quant.wave_attn(q, k, v) # FP8 WMMA, 3-8x faster than SDPA
116
+ out = hip_quant.wave_attn(q, k, v) # native FP8 WMMA (inference-grade)
117
+ # Native FP16 WMMA training kernels on gfx1201 (forward + backward, no Triton):
118
+ qh, kh, vh = q.half(), k.half(), v.half()
119
+ out_fp16 = hip_quant.wave_attn(qh, kh, vh, precision="fp16")
120
+ # BF16 Triton fallback (requires ROCm Triton):
121
+ qbf, kbf, vbf = q.bfloat16(), k.bfloat16(), v.bfloat16()
122
+ out_bf16 = hip_quant.wave_attn(qbf, kbf, vbf, precision="bf16")
123
+ # Or defer to PyTorch SDPA entirely:
124
+ out_precise = hip_quant.wave_attn(q, k, v, precision="sdpa")
89
125
  ```
90
126
 
91
127
  **Key features:**
@@ -97,7 +133,7 @@ out = hip_quant.wave_attn(q, k, v) # FP8 WMMA, 3-8x faster than SDPA
97
133
  - Multi-split parallelism for low-occupancy configs
98
134
  - Native INT4 WMMA path (`wave_attn_int4`) — Q/K 4-bit, V FP8, LUT unpack (new in 1.3.0)
99
135
 
100
- **Performance — RX 9070 XT `gfx1201`, `ROCm 7.2.1` + `torch 2.9.1+rocm7.2.1`, `D=128` (measured `bench_attn.py` vs `F.scaled_dot_product_attention`/AOTriton):**
136
+ **Historical performance — RX 9070 XT `gfx1201`, `ROCm 7.2.1` + `torch 2.9.1+rocm7.2.1`, `D=128` (measured `bench_attn.py` against its AOTriton SDPA path):**
101
137
 
102
138
  | Config (B,H,S,D) | Causal | `wave` fwd | `SDPA` fwd | fwd speedup | `wave` bwd | `SDPA` bwd | bwd speedup |
103
139
  |---|:---:|---|---|---|---|---|---|
@@ -109,9 +145,44 @@ out = hip_quant.wave_attn(q, k, v) # FP8 WMMA, 3-8x faster than SDPA
109
145
  | 1,32,256,128 | Y | 0.139 ms | 0.370 ms | **2.66×** | 0.298 ms | 1.158 ms | **3.89×** |
110
146
  | 1,32,1024,128 | Y | 0.792 ms | 4.422 ms | **5.59×** | 2.878 ms | 10.632 ms | **3.69×** |
111
147
 
112
- Accuracy: FP8 `cos ~0.9986-0.999` vs FP32 reference, backward `dQ 0.9981 / dK 0.9986 / dV 0.9999`, stable across `S`.
113
-
114
- > **Why not FA3?** FlashAttention-3 is `Hopper` (`sm90`) CUDA-only — no ROCm/HIP port and no `gfx12` codegen. The fair ROCm baseline is `PyTorch SDPA` which on ROCm routes to `AOTriton` (`Efficient Attention`). `wave_attn` beats that path by specializing for `gfx1200/1201` `WMMA` directly.
148
+ The table describes that benchmark's backend and shapes; it is not a current
149
+ speed claim for every SDPA backend or training shape. On the same RX 9070 XT
150
+ with `B=6,H=12,S=789,D=64` BF16 inputs, the full native FP8 training API
151
+ takes **1.87 ms** forward plus backward, while `precision="sdpa"` takes
152
+ **1.03 ms**. Against BF16 MATH SDPA, native dQ/dK relative L2 is about 8%
153
+ at input scale 1 and 58% at scale 5; the SDPA precision mode is below 1%.
154
+ See `benchmarks/wave_attn_train_results.md` for methods and all metrics.
155
+
156
+ > The native FP8 path remains available with `precision="native"` (the default),
157
+ > including for prequantized `uint8` inputs. The SDPA precision mode is for
158
+ > floating-point training inputs and returns a float32 output.
159
+
160
+ **BF16 training mode (experimental):** `precision="bf16"` uses Triton kernels
161
+ that compile to gfx1201 `v_wmma_f32_16x16x16_bf16` instructions. It accepts
162
+ contiguous, equal-shaped BF16 Q/K/V with head dimension 64 or 128; the output
163
+ and input gradients are BF16. A separate FP32 output is saved for backward so
164
+ large-score gradients retain accuracy. The full public forward/backward call
165
+ beats default BF16 SDPA on the RX 9070 XT at `B=6,H=12,S=789`: 0.75 vs 1.02 ms
166
+ for D=64 noncausal, 0.35 vs 0.98 ms causal; 2.24 vs 2.85 ms for D=128
167
+ noncausal, 1.41 vs 1.96 ms causal (100 GPU-event repeats, medians of three
168
+ rounds). Output and gradient relative L2 against FP32 MATH stay below 0.26%
169
+ at input scales 1 and 5. Small attention calls can be slower than SDPA, so
170
+ select this mode for measured training workloads. See
171
+ `benchmarks/check_wave_attn_train_gate.py`,
172
+ `benchmarks/check_plant_wave_continuation.py`, and
173
+ `benchmarks/wave_attn_train_results.md` for the checks.
174
+
175
+ To route timm's SDPA calls through the BF16 path, set
176
+ `HIP_QUANT_WAVE_ATTN_PRECISION=bf16` before calling `patch_sdpa()` (or before a
177
+ trainer's `--wave-attention` flag). The helper makes timm's transposed Q/K/V
178
+ views contiguous and returns BF16 outputs; unsupported attention shapes still
179
+ use SDPA. A BF16 kernel error propagates instead of silently falling back.
180
+ From a real PlantUnified checkpoint at step 131,780, the BF16 path completed
181
+ 3,000 more training updates with finite loss and gradients, using 24 attention
182
+ calls per update across the 12 DINOv3 blocks and their checkpoint recomputations.
183
+ The bounded run did not perform EMA or validation; the eight-step matched A/B
184
+ ended at loss 7.7051 (BF16 WaveAttention) versus 7.7122 (BF16 SDPA). A
185
+ full-model speed win and full-epoch convergence remain unverified.
115
186
 
116
187
  ## HQ2 / HQ3 — experimental learned-codebook formats
117
188
 
@@ -349,7 +420,7 @@ pip install hip-quant
349
420
  pip install "hip-quant[torch]"
350
421
 
351
422
  # Or a local wheel
352
- pip install dist/hip_quant-2.2.0-cp312-cp312-win_amd64.whl
423
+ pip install dist/hip_quant-2.2.3-cp312-cp312-win_amd64.whl
353
424
  ```
354
425
 
355
426
  Two wheels are published per release, one per PyTorch ABI. Install the one that
@@ -357,11 +428,11 @@ matches your PyTorch, so the extension loads without an ABI mismatch:
357
428
 
358
429
  | Wheel | PyTorch | ROCm |
359
430
  |---|---|---|
360
- | `hip-quant==2.2.2` | 2.9.x | ROCm 7.2.1 |
361
- | `hip-quant==2.2.2.post215` | 2.15 / TheRock | ROCm 7.14 |
431
+ | `hip-quant==2.2.3` | 2.9.x | ROCm 7.2.1 |
432
+ | `hip-quant==2.2.3.post215` | 2.15 / TheRock | ROCm 7.14 |
362
433
 
363
434
  ```powershell
364
- pip install "hip-quant==2.2.2.post215" # PyTorch 2.15 / TheRock
435
+ pip install "hip-quant==2.2.3.post215" # PyTorch 2.15 / TheRock
365
436
  ```
366
437
 
367
438
  #### Custom PyTorch 2.15 (self-hosted wheels)
@@ -371,7 +442,7 @@ Its wheels live in a public Backblaze B2 bucket; point pip at the index page
371
442
  with `--find-links`:
372
443
 
373
444
  ```powershell
374
- pip install "hip-quant==2.2.2.post215" `
445
+ pip install "hip-quant==2.2.3.post215" `
375
446
  --find-links https://dl.hipquant.download/file/Torchs/torch_index.html
376
447
  ```
377
448
 
@@ -0,0 +1,4 @@
1
+ [diffend] Oversized file quarantined before diffing.
2
+ name: hip_quant-2.2.3/_C.cp312-win_amd64.pyd
3
+ size: 41630720 bytes
4
+ sha256: 7f845ecb6d26ac4de5f61c9da5bd3ffaa88eb549d60a350dfe29832e50b24a36
@@ -3,7 +3,7 @@ import numpy as np
3
3
  import os
4
4
  import sys
5
5
 
6
- __version__ = "2.2.2"
6
+ __version__ = "2.2.3"
7
7
 
8
8
 
9
9
  _TORCH_EXPORTS = {
@@ -66,6 +66,10 @@ GGML_TYPES: Dict[int, Tuple[str, int, int]] = {
66
66
  30: ("BF16", 2, 1),
67
67
  34: ("TQ1_0", 54, 256),
68
68
  35: ("TQ2_0", 66, 256),
69
+ # Prism-private ternary: one FP16 scale + 26 packed trit bytes per 128
70
+ # weights. The byte codec is intentionally handled by HQNAT's Prism
71
+ # importer rather than pretending this is upstream TQ1_0.
72
+ 143:("PTQ1_0", 28, 128),
69
73
  39: ("MXFP4", 17, 32),
70
74
  40: ("NVFP4", 36, 64),
71
75
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hip-quant
3
- Version: 2.2.2
3
+ Version: 2.2.3
4
4
  Summary: High-performance GPU tensor quantization and inference engine for AMD ROCm. Native AOT GEMV (K-Quants & I-Quants), State Space Model (SSM/DeltaNet) kernels, FP8 WMMA WaveAttention, and portable HIP C++ kernels for RDNA4, RDNA3, and CDNA.
5
5
  Author-email: Thenukegun10x <conormorris84@gmail.com>
6
6
  License: Apache License
@@ -239,6 +239,34 @@ Dynamic: license-file
239
239
 
240
240
  `hip-quant` is a standalone Python library and highly optimized HIP C++ backend for tensor quantization and accelerated LLM inference on AMD GPUs with zero CPU round-trips.
241
241
 
242
+ > ⚠️ **Numerical / experimental status — WaveAttention training kernels.**
243
+ > The WaveAttention **training** paths are experimental. The native FP8 path
244
+ > (`precision="native"`, the default) is an inference-grade kernel: against a
245
+ > BF16 MATH-SDPA reference its `dQ`/`dK` relative L2 is about **8% at input
246
+ > scale 1 and ~58% at scale 5**, so it is *not* suitable for training as-is.
247
+ > The `precision="fp16"` native WMMA kernels (new in 2.2.3) are the accurate
248
+ > choice: against an fp32 SDPA reference the forward/backward relative L2 is
249
+ > ~2e-4 / ~3e-4 at the tested shapes and input scales, and an adversarial
250
+ > NaN/Inf + extreme-range harness passes clean. The `precision="bf16"` Triton
251
+ > kernels are kept as a fallback. **Full-model convergence and end-to-end speed
252
+ > remain unverified** (a 3,000-update PlantUnified continuation was finite,
253
+ > without EMA/validation). A CPU float64 operand study
254
+ > (`benchmarks/wave_attn_train_results.md`) found that no FP8 operand mixture —
255
+ > including Hadamard-rotated, block-scaled FP8 — reaches a sub-1% training
256
+ > target; f16 WMMA operands are the accurate choice. **Validate accuracy and
257
+ > convergence on your own workload before training with any of these paths.**
258
+
259
+ ## 🌟 What's New in 2.2.3
260
+
261
+ > **2.2.3.post215** is the same release rebuilt against PyTorch 2.15 (TheRock / ROCm 7.14).
262
+
263
+ - **🌊 Native FP16 WMMA training attention (`gfx1201`).** `wave_attn(..., precision="fp16")` now runs a purpose-built FP16 flash-attention **forward and backward** on `v_wmma_f32_16x16x16_f16` — no Triton, and no SDPA recomputation for the backward. `dQ`/`dK`/`dV` are computed on-device with a FlashAttention-2 preprocess pass for `D_i = Σ_d dO_id·O_id`. Against the AOTriton SDPA baseline (`F.scaled_dot_product_attention`, flash backend) at `B1 H16`, the **forward is faster on all eight measured shapes** (1.35–2.13×; 60.9–68.4 vs 44.8–50.9 TFLOP/s at `S4096`). The **backward is still behind AOTriton** (1.47–2.06× slower; 14–22 vs 26–38 TFLOP/s): its `dK`/`dV` block needs one wave per 16-key sub-tile and ~53 KB of shared memory, which caps it at four waves per CTA and one CTA per CU.
264
+ - **🐛 Three training-correctness bugs found and fixed**, by a new adversarial harness (`tests/torch/test_wave_attn_f16_extreme.py`: ~70 hand-built cases plus a log-uniform fuzz against an fp64 reference):
265
+ - **`dS` fp16 overflow → NaN.** `|dS| ≈ 3.41·|V|·|dO|` at `D=128`, so perfectly valid fp16 inputs (`V=65504`, `dO=1`) overflowed the `dS` store and produced NaN gradients. A per-`(b,h)` scale from the preprocess pass now bounds `dS`, and the output is divided back out; the `min(1, …)` cap keeps ordinary inputs bit-identical to the unscaled kernel.
266
+ - **Causal mask mismatch when `Seq_K > Seq_Q`.** The FP16 forward carried a bottom-right offset while the backward — and PyTorch's `is_causal` — are strictly top-left. The offset is gone, so forward and backward now agree.
267
+ - **`LSE` log-term loss.** Storing `row max + log(row sum)` as a single fp32 rounded the log term away once the max exceeded ~4e7, making `dV` exactly **128× too large** and turning a cancellation residual into a spurious `dQ` of 1.44e7 where the true value is exactly 0. `LSE` is now two fp32 per row, subtracted separately.
268
+ - **🛡️ The forward can no longer overflow fp32.** Scores stay in the raw WMMA domain and `softmax_scale` is applied *inside* the exponent as `(raw − raw)·|scale|`. Forming `sacc·scale` was the forward's only fp32 overflow site (`|sacc| ≤ D·65504² = 5.5e11`, so `scale > 6.19e26` NaNs everything downstream) — and PyTorch's own fp32 SDPA and a textbook fp32 softmax **do** NaN at exactly that threshold. The native kernel now matches fp64 exactly there, while still agreeing with SDPA to ~2e-4 in the normal range. A negative `softmax_scale` (softmax of `−s`) is normalised out, so it is unaffected.
269
+
242
270
  ## 🌟 What's New in 2.2.2
243
271
 
244
272
  > **2.2.2.post215** is the same release rebuilt against PyTorch 2.15 (TheRock / ROCm 7.14).
@@ -310,7 +338,15 @@ q = torch.randn(4, 8, 256, 64, device="cuda")
310
338
  k = torch.randn(4, 8, 256, 64, device="cuda")
311
339
  v = torch.randn(4, 8, 256, 64, device="cuda")
312
340
 
313
- out = hip_quant.wave_attn(q, k, v) # FP8 WMMA, 3-8x faster than SDPA
341
+ out = hip_quant.wave_attn(q, k, v) # native FP8 WMMA (inference-grade)
342
+ # Native FP16 WMMA training kernels on gfx1201 (forward + backward, no Triton):
343
+ qh, kh, vh = q.half(), k.half(), v.half()
344
+ out_fp16 = hip_quant.wave_attn(qh, kh, vh, precision="fp16")
345
+ # BF16 Triton fallback (requires ROCm Triton):
346
+ qbf, kbf, vbf = q.bfloat16(), k.bfloat16(), v.bfloat16()
347
+ out_bf16 = hip_quant.wave_attn(qbf, kbf, vbf, precision="bf16")
348
+ # Or defer to PyTorch SDPA entirely:
349
+ out_precise = hip_quant.wave_attn(q, k, v, precision="sdpa")
314
350
  ```
315
351
 
316
352
  **Key features:**
@@ -322,7 +358,7 @@ out = hip_quant.wave_attn(q, k, v) # FP8 WMMA, 3-8x faster than SDPA
322
358
  - Multi-split parallelism for low-occupancy configs
323
359
  - Native INT4 WMMA path (`wave_attn_int4`) — Q/K 4-bit, V FP8, LUT unpack (new in 1.3.0)
324
360
 
325
- **Performance — RX 9070 XT `gfx1201`, `ROCm 7.2.1` + `torch 2.9.1+rocm7.2.1`, `D=128` (measured `bench_attn.py` vs `F.scaled_dot_product_attention`/AOTriton):**
361
+ **Historical performance — RX 9070 XT `gfx1201`, `ROCm 7.2.1` + `torch 2.9.1+rocm7.2.1`, `D=128` (measured `bench_attn.py` against its AOTriton SDPA path):**
326
362
 
327
363
  | Config (B,H,S,D) | Causal | `wave` fwd | `SDPA` fwd | fwd speedup | `wave` bwd | `SDPA` bwd | bwd speedup |
328
364
  |---|:---:|---|---|---|---|---|---|
@@ -334,9 +370,44 @@ out = hip_quant.wave_attn(q, k, v) # FP8 WMMA, 3-8x faster than SDPA
334
370
  | 1,32,256,128 | Y | 0.139 ms | 0.370 ms | **2.66×** | 0.298 ms | 1.158 ms | **3.89×** |
335
371
  | 1,32,1024,128 | Y | 0.792 ms | 4.422 ms | **5.59×** | 2.878 ms | 10.632 ms | **3.69×** |
336
372
 
337
- Accuracy: FP8 `cos ~0.9986-0.999` vs FP32 reference, backward `dQ 0.9981 / dK 0.9986 / dV 0.9999`, stable across `S`.
338
-
339
- > **Why not FA3?** FlashAttention-3 is `Hopper` (`sm90`) CUDA-only — no ROCm/HIP port and no `gfx12` codegen. The fair ROCm baseline is `PyTorch SDPA` which on ROCm routes to `AOTriton` (`Efficient Attention`). `wave_attn` beats that path by specializing for `gfx1200/1201` `WMMA` directly.
373
+ The table describes that benchmark's backend and shapes; it is not a current
374
+ speed claim for every SDPA backend or training shape. On the same RX 9070 XT
375
+ with `B=6,H=12,S=789,D=64` BF16 inputs, the full native FP8 training API
376
+ takes **1.87 ms** forward plus backward, while `precision="sdpa"` takes
377
+ **1.03 ms**. Against BF16 MATH SDPA, native dQ/dK relative L2 is about 8%
378
+ at input scale 1 and 58% at scale 5; the SDPA precision mode is below 1%.
379
+ See `benchmarks/wave_attn_train_results.md` for methods and all metrics.
380
+
381
+ > The native FP8 path remains available with `precision="native"` (the default),
382
+ > including for prequantized `uint8` inputs. The SDPA precision mode is for
383
+ > floating-point training inputs and returns a float32 output.
384
+
385
+ **BF16 training mode (experimental):** `precision="bf16"` uses Triton kernels
386
+ that compile to gfx1201 `v_wmma_f32_16x16x16_bf16` instructions. It accepts
387
+ contiguous, equal-shaped BF16 Q/K/V with head dimension 64 or 128; the output
388
+ and input gradients are BF16. A separate FP32 output is saved for backward so
389
+ large-score gradients retain accuracy. The full public forward/backward call
390
+ beats default BF16 SDPA on the RX 9070 XT at `B=6,H=12,S=789`: 0.75 vs 1.02 ms
391
+ for D=64 noncausal, 0.35 vs 0.98 ms causal; 2.24 vs 2.85 ms for D=128
392
+ noncausal, 1.41 vs 1.96 ms causal (100 GPU-event repeats, medians of three
393
+ rounds). Output and gradient relative L2 against FP32 MATH stay below 0.26%
394
+ at input scales 1 and 5. Small attention calls can be slower than SDPA, so
395
+ select this mode for measured training workloads. See
396
+ `benchmarks/check_wave_attn_train_gate.py`,
397
+ `benchmarks/check_plant_wave_continuation.py`, and
398
+ `benchmarks/wave_attn_train_results.md` for the checks.
399
+
400
+ To route timm's SDPA calls through the BF16 path, set
401
+ `HIP_QUANT_WAVE_ATTN_PRECISION=bf16` before calling `patch_sdpa()` (or before a
402
+ trainer's `--wave-attention` flag). The helper makes timm's transposed Q/K/V
403
+ views contiguous and returns BF16 outputs; unsupported attention shapes still
404
+ use SDPA. A BF16 kernel error propagates instead of silently falling back.
405
+ From a real PlantUnified checkpoint at step 131,780, the BF16 path completed
406
+ 3,000 more training updates with finite loss and gradients, using 24 attention
407
+ calls per update across the 12 DINOv3 blocks and their checkpoint recomputations.
408
+ The bounded run did not perform EMA or validation; the eight-step matched A/B
409
+ ended at loss 7.7051 (BF16 WaveAttention) versus 7.7122 (BF16 SDPA). A
410
+ full-model speed win and full-epoch convergence remain unverified.
340
411
 
341
412
  ## HQ2 / HQ3 — experimental learned-codebook formats
342
413
 
@@ -574,7 +645,7 @@ pip install hip-quant
574
645
  pip install "hip-quant[torch]"
575
646
 
576
647
  # Or a local wheel
577
- pip install dist/hip_quant-2.2.0-cp312-cp312-win_amd64.whl
648
+ pip install dist/hip_quant-2.2.3-cp312-cp312-win_amd64.whl
578
649
  ```
579
650
 
580
651
  Two wheels are published per release, one per PyTorch ABI. Install the one that
@@ -582,11 +653,11 @@ matches your PyTorch, so the extension loads without an ABI mismatch:
582
653
 
583
654
  | Wheel | PyTorch | ROCm |
584
655
  |---|---|---|
585
- | `hip-quant==2.2.2` | 2.9.x | ROCm 7.2.1 |
586
- | `hip-quant==2.2.2.post215` | 2.15 / TheRock | ROCm 7.14 |
656
+ | `hip-quant==2.2.3` | 2.9.x | ROCm 7.2.1 |
657
+ | `hip-quant==2.2.3.post215` | 2.15 / TheRock | ROCm 7.14 |
587
658
 
588
659
  ```powershell
589
- pip install "hip-quant==2.2.2.post215" # PyTorch 2.15 / TheRock
660
+ pip install "hip-quant==2.2.3.post215" # PyTorch 2.15 / TheRock
590
661
  ```
591
662
 
592
663
  #### Custom PyTorch 2.15 (self-hosted wheels)
@@ -596,7 +667,7 @@ Its wheels live in a public Backblaze B2 bucket; point pip at the index page
596
667
  with `--find-links`:
597
668
 
598
669
  ```powershell
599
- pip install "hip-quant==2.2.2.post215" `
670
+ pip install "hip-quant==2.2.3.post215" `
600
671
  --find-links https://dl.hipquant.download/file/Torchs/torch_index.html
601
672
  ```
602
673
 
@@ -28,6 +28,8 @@ setup.py
28
28
  setup_torch.py
29
29
  smi.py
30
30
  torch_api.py
31
+ wave_attn_train_strided_triton.py
32
+ wave_attn_train_triton.py
31
33
  wave_helpers.py
32
34
  ./_C.cp312-win_amd64.pyd
33
35
  ./__init__.py
@@ -54,6 +56,8 @@ wave_helpers.py
54
56
  ./setup_torch.py
55
57
  ./smi.py
56
58
  ./torch_api.py
59
+ ./wave_attn_train_strided_triton.py
60
+ ./wave_attn_train_triton.py
57
61
  ./wave_helpers.py
58
62
  ./codebooks/iq1_s.bin
59
63
  ./codebooks/iq2_s.bin
@@ -144,10 +148,15 @@ wave_helpers.py
144
148
  ./tests/torch/test_q_to_fp8_torch.py
145
149
  ./tests/torch/test_quant_transpose.py
146
150
  ./tests/torch/test_wave_attn_backward_math.py
151
+ ./tests/torch/test_wave_attn_f16.py
152
+ ./tests/torch/test_wave_attn_f16_extreme.py
153
+ ./tests/torch/test_wave_attn_train_bf16.py
154
+ ./tests/torch/test_wave_helpers_cpu.py
147
155
  ./tools/.gpu-smi-version
148
156
  ./tools/fetch_gpu_smi.py
149
157
  ./tools/gpu-smi.exe
150
158
  ./torch_ext/current_stream.hip
159
+ ./torch_ext/decode_quant_kernels.hip
151
160
  ./torch_ext/dequant_q_to_fp16.hip
152
161
  ./torch_ext/fp8_linear_kernels.hip
153
162
  ./torch_ext/fp8_linear_kernels_v2.hip
@@ -156,6 +165,7 @@ wave_helpers.py
156
165
  ./torch_ext/hq2_linear_kernels.hip
157
166
  ./torch_ext/hq3_linear_kernels.hip
158
167
  ./torch_ext/hq8_g128_linear_kernels.hip
168
+ ./torch_ext/int4_wmma_kernels.hip
159
169
  ./torch_ext/iq_grid_tables.h
160
170
  ./torch_ext/kv_iu4_kernels.hip
161
171
  ./torch_ext/mxfp4_to_fp8_kernels.hip
@@ -164,13 +174,18 @@ wave_helpers.py
164
174
  ./torch_ext/pytorch_bindings_hip.cpp
165
175
  ./torch_ext/q_to_fp8_kernels.hip
166
176
  ./torch_ext/ssm_kernels.hip
177
+ ./torch_ext/ternary_gemv_kernels.hip
178
+ ./torch_ext/w4a16_gemv_kernels.hip
167
179
  ./torch_ext/wave_attn.hip
168
180
  ./torch_ext/wave_attn_backward.hip
181
+ ./torch_ext/wave_attn_backward_f16.hip
169
182
  ./torch_ext/wave_attn_common.h
170
183
  ./torch_ext/wave_attn_decode.hip
171
184
  ./torch_ext/wave_attn_diag.hip
185
+ ./torch_ext/wave_attn_f16.hip
172
186
  ./torch_ext/wave_attn_long.hip
173
187
  ./torch_ext/wave_attn_prefill.hip
188
+ ./torch_ext/wht_kernels.hip
174
189
  codebooks/iq1_s.bin
175
190
  codebooks/iq2_s.bin
176
191
  codebooks/iq2_xs.bin
@@ -282,6 +297,10 @@ tests/torch/test_mxfp8_torch.py
282
297
  tests/torch/test_q_to_fp8_torch.py
283
298
  tests/torch/test_quant_transpose.py
284
299
  tests/torch/test_wave_attn_backward_math.py
300
+ tests/torch/test_wave_attn_f16.py
301
+ tests/torch/test_wave_attn_f16_extreme.py
302
+ tests/torch/test_wave_attn_train_bf16.py
303
+ tests/torch/test_wave_helpers_cpu.py
285
304
  tools/.gpu-smi-version
286
305
  tools/fetch_gpu_smi.py
287
306
  tools/gpu-smi.exe
@@ -296,6 +315,7 @@ tools/mlp_codec/run_ladder.py
296
315
  tools/mlp_codec/safe_run.py
297
316
  tools/mlp_codec/validate_hessians.py
298
317
  torch_ext/current_stream.hip
318
+ torch_ext/decode_quant_kernels.hip
299
319
  torch_ext/dequant_q_to_fp16.hip
300
320
  torch_ext/fp8_linear_kernels.hip
301
321
  torch_ext/fp8_linear_kernels_v2.hip
@@ -304,6 +324,7 @@ torch_ext/gemv_q_kernels.hip
304
324
  torch_ext/hq2_linear_kernels.hip
305
325
  torch_ext/hq3_linear_kernels.hip
306
326
  torch_ext/hq8_g128_linear_kernels.hip
327
+ torch_ext/int4_wmma_kernels.hip
307
328
  torch_ext/iq_grid_tables.h
308
329
  torch_ext/kv_iu4_kernels.hip
309
330
  torch_ext/mxfp4_to_fp8_kernels.hip
@@ -312,10 +333,15 @@ torch_ext/pytorch_bindings.cpp
312
333
  torch_ext/pytorch_bindings_hip.cpp
313
334
  torch_ext/q_to_fp8_kernels.hip
314
335
  torch_ext/ssm_kernels.hip
336
+ torch_ext/ternary_gemv_kernels.hip
337
+ torch_ext/w4a16_gemv_kernels.hip
315
338
  torch_ext/wave_attn.hip
316
339
  torch_ext/wave_attn_backward.hip
340
+ torch_ext/wave_attn_backward_f16.hip
317
341
  torch_ext/wave_attn_common.h
318
342
  torch_ext/wave_attn_decode.hip
319
343
  torch_ext/wave_attn_diag.hip
344
+ torch_ext/wave_attn_f16.hip
320
345
  torch_ext/wave_attn_long.hip
321
- torch_ext/wave_attn_prefill.hip
346
+ torch_ext/wave_attn_prefill.hip
347
+ torch_ext/wht_kernels.hip
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "hip-quant"
7
- version = "2.2.2"
7
+ version = "2.2.3"
8
8
  description = "High-performance GPU tensor quantization and inference engine for AMD ROCm. Native AOT GEMV (K-Quants & I-Quants), State Space Model (SSM/DeltaNet) kernels, FP8 WMMA WaveAttention, and portable HIP C++ kernels for RDNA4, RDNA3, and CDNA."
9
9
  readme = "README.md"
10
10
 
@@ -88,6 +88,8 @@ include-package-data = false
88
88
  "torch_ext/pytorch_bindings.cpp",
89
89
  "torch_ext/pytorch_bindings_hip.cpp",
90
90
  "torch_api.py",
91
+ "wave_attn_train_triton.py",
92
+ "wave_attn_train_strided_triton.py",
91
93
  "gguf.py",
92
94
  "gguf_loader.py",
93
95
  "wave_helpers.py",
@@ -163,9 +163,11 @@ def _torch_extension_config():
163
163
  "torch_ext/wave_attn_prefill.hip",
164
164
  "torch_ext/wave_attn_decode.hip",
165
165
  "torch_ext/wave_attn_long.hip",
166
+ "torch_ext/decode_quant_kernels.hip",
166
167
  "torch_ext/gemv_q_kernels.hip",
167
168
  "torch_ext/ssm_kernels.hip",
168
169
  "torch_ext/kv_iu4_kernels.hip",
170
+ "torch_ext/int4_wmma_kernels.hip",
169
171
  "torch_ext/dequant_q_to_fp16.hip",
170
172
  ],
171
173
 
@@ -149,12 +149,19 @@ ext = CUDAExtension(
149
149
  "torch_ext/hq2_linear_kernels.hip",
150
150
  "torch_ext/hq3_linear_kernels.hip",
151
151
  "torch_ext/hq8_g128_linear_kernels.hip",
152
+ "torch_ext/int4_wmma_kernels.hip",
153
+ "torch_ext/w4a16_gemv_kernels.hip",
154
+ "torch_ext/ternary_gemv_kernels.hip",
155
+ "torch_ext/wht_kernels.hip",
152
156
  "torch_ext/wave_attn.hip",
153
157
  "torch_ext/wave_attn_backward.hip",
158
+ "torch_ext/wave_attn_f16.hip",
159
+ "torch_ext/wave_attn_backward_f16.hip",
154
160
  "torch_ext/wave_attn_diag.hip",
155
161
  "torch_ext/wave_attn_prefill.hip",
156
162
  "torch_ext/wave_attn_decode.hip",
157
163
  "torch_ext/wave_attn_long.hip",
164
+ "torch_ext/decode_quant_kernels.hip",
158
165
  "torch_ext/gemv_q_kernels.hip",
159
166
  "torch_ext/ssm_kernels.hip",
160
167
  "torch_ext/kv_iu4_kernels.hip",