Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -273,3 +273,19 @@ jobs:
/opt/rocm/bin/hipcc --offload-arch=gfx1151 -O2 \
-o "$RUNNER_TEMP/hip_smoke" .github/ci/hip_smoke.cpp
"$RUNNER_TEMP/hip_smoke"

- name: Build + test ROCmFP formats
run: |
cmake -S server -B "$RUNNER_TEMP/rocmfp-build" \
-DDFLASH27B_GPU_BACKEND=hip \
-DDFLASH27B_HIP_ARCHITECTURES=gfx1151 \
-DDFLASH27B_SERVER=OFF \
-DDFLASH27B_TESTS=ON \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_HIP_FLAGS=-DDFLASH_WAVE_SIZE=32
cmake --build "$RUNNER_TEMP/rocmfp-build" \
--target test_rocmfp4 test_rocmfpx test_rocmfp4_hip_tail \
--parallel 8
ctest --test-dir "$RUNNER_TEMP/rocmfp-build" \
--output-on-failure \
-R 'rocmfp4_reference|rocmfpx_reference|rocmfp4_hip_tail'
30 changes: 30 additions & 0 deletions server/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,36 @@ if(DFLASH27B_TESTS)
${DFLASH27B_GGML_BACKEND_TARGET} ggml ggml-base)
add_test(NAME cuda_pool_shutdown COMMAND test_cuda_pool_shutdown)
endif()

add_executable(test_rocmfp4 deps/llama.cpp/ggml/rocmfp4/test_rocmfp4.c)
target_link_libraries(test_rocmfp4 PRIVATE ggml-base)
if(UNIX)
target_link_libraries(test_rocmfp4 PRIVATE m)
endif()
add_test(NAME rocmfp4_reference COMMAND test_rocmfp4)

add_executable(test_rocmfpx deps/llama.cpp/ggml/rocmfpx/test_rocmfpx.c)
target_link_libraries(test_rocmfpx PRIVATE ggml-base)
if(UNIX)
target_link_libraries(test_rocmfpx PRIVATE m)
endif()
add_test(NAME rocmfpx_reference COMMAND test_rocmfpx)

if(DFLASH27B_GPU_BACKEND STREQUAL "hip")
add_executable(test_rocmfp4_hip_tail test/test_rocmfp4_hip_tail.cpp)
set_source_files_properties(test/test_rocmfp4_hip_tail.cpp PROPERTIES LANGUAGE HIP)
set_target_properties(test_rocmfp4_hip_tail PROPERTIES HIP_ARCHITECTURES "${_dflash_archs}")
target_include_directories(test_rocmfp4_hip_tail PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/deps/llama.cpp/ggml/include
${CMAKE_CURRENT_SOURCE_DIR}/deps/llama.cpp/ggml/rocmfp4)
target_link_libraries(test_rocmfp4_hip_tail PRIVATE
ggml
ggml-base
${DFLASH27B_GGML_BACKEND_TARGET}
hip::host)
add_test(NAME rocmfp4_hip_tail COMMAND test_rocmfp4_hip_tail)
endif()

if(DFLASH27B_GPU_BACKEND STREQUAL "cuda" AND _dflash_cuda_min_sm GREATER_EQUAL 80 AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/test_flashprefill_kernels.cpp")
add_executable(test_flashprefill_kernels test/test_flashprefill_kernels.cpp)
set_target_properties(test_flashprefill_kernels PROPERTIES CUDA_ARCHITECTURES "${_dflash_archs}")
Expand Down
60 changes: 59 additions & 1 deletion server/deps/llama.cpp/ggml/include/ggml.h
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,13 @@ extern "C" {
GGML_TYPE_NVFP4 = 40, // NVFP4 (4 blocks, E4M3 scale)
GGML_TYPE_Q1_0 = 41,
GGML_TYPE_TQ3_0 = 42, // TurboQuant 3.5 bpv (3-bit Lloyd-Max + FWHT rotation)
GGML_TYPE_COUNT = 43,
GGML_TYPE_Q4_0_ROCMFP4 = 100,
GGML_TYPE_Q4_0_ROCMFP4_FAST = 101,
GGML_TYPE_Q6_0_ROCMFPX = 102,
GGML_TYPE_Q8_0_ROCMFPX = 103,
GGML_TYPE_Q3_0_ROCMFPX = 104,
GGML_TYPE_Q2_0_ROCMFP2 = 107,
GGML_TYPE_COUNT = 108,
};

// precision
Expand Down Expand Up @@ -468,6 +474,18 @@ extern "C" {
GGML_FTYPE_MOSTLY_MXFP4 = 25, // except 1d tensors
GGML_FTYPE_MOSTLY_NVFP4 = 26, // except 1d tensors
GGML_FTYPE_MOSTLY_Q1_0 = 27, // except 1d tensors
GGML_FTYPE_MOSTLY_Q4_0_ROCMFP4 = 100,
GGML_FTYPE_MOSTLY_Q4_0_ROCMFP4_LEAN = 101,
GGML_FTYPE_MOSTLY_Q4_0_ROCMFP4_COHERENT = 102,
GGML_FTYPE_MOSTLY_Q4_0_ROCMFP4_FAST = 103,
GGML_FTYPE_MOSTLY_Q4_0_ROCMFP4_FAST_COHERENT = 104,
GGML_FTYPE_MOSTLY_Q4_0_ROCMFP4_STRIX = 105,
GGML_FTYPE_MOSTLY_Q4_0_ROCMFP4_STRIX_LEAN = 106,
GGML_FTYPE_MOSTLY_Q6_0_ROCMFPX = 110,
GGML_FTYPE_MOSTLY_Q8_0_ROCMFPX = 111,
GGML_FTYPE_MOSTLY_Q3_0_ROCMFPX = 112,
GGML_FTYPE_MOSTLY_Q2_0_ROCMFP2 = 118,
GGML_FTYPE_MOSTLY_Q2_0_ROCMFP2_STRIX = 119,
};

// available tensor operations:
Expand Down Expand Up @@ -583,6 +601,8 @@ extern "C" {

GGML_OP_MOE_FUSED, // Fused MoE FFN: gate+up+swiglu+down+weighted_sum+shared_expert

GGML_OP_DS4_HC, // Fused DeepSeek4 hyper-connection pre/post/out mixing

GGML_OP_COUNT,
};

Expand Down Expand Up @@ -618,6 +638,7 @@ extern "C" {
GGML_GLU_OP_GEGLU,
GGML_GLU_OP_SWIGLU,
GGML_GLU_OP_SWIGLU_OAI,
GGML_GLU_OP_SWIGLU_DS4,
GGML_GLU_OP_GEGLU_ERF,
GGML_GLU_OP_GEGLU_QUICK,

Expand Down Expand Up @@ -1339,6 +1360,12 @@ extern "C" {
struct ggml_tensor * a,
struct ggml_tensor * b);

GGML_API struct ggml_tensor * ggml_swiglu_ds4_split(
struct ggml_context * ctx,
struct ggml_tensor * gate,
struct ggml_tensor * up,
float clamp);

GGML_API struct ggml_tensor * ggml_geglu_erf_split(
struct ggml_context * ctx,
struct ggml_tensor * a,
Expand Down Expand Up @@ -2399,6 +2426,37 @@ extern "C" {
struct ggml_tensor * experts,
struct ggml_tensor * expert_weights);

// Fused DeepSeek4 hyper-connection helpers (decode, n_tokens == 1).
// ggml_ds4_hc_pre: mix[2*n_hc+n_hc^2] + base + hc_state[n_embd*n_hc] ->
// dst[n_embd + 2*n_hc + n_hc^2] = { working, split(pre,post,comb) }
GGML_API struct ggml_tensor * ggml_ds4_hc_pre(
struct ggml_context * ctx,
struct ggml_tensor * mix,
struct ggml_tensor * base,
struct ggml_tensor * hc_state,
int n_hc,
int sinkhorn_iters,
float pre_scale,
float post_scale,
float comb_scale);

// ggml_ds4_hc_post: residual hc_state + block_out + split -> new hc_state
GGML_API struct ggml_tensor * ggml_ds4_hc_post(
struct ggml_context * ctx,
struct ggml_tensor * residual_hc,
struct ggml_tensor * block_out,
struct ggml_tensor * split,
int n_hc);

// ggml_ds4_hc_out: output-stage merge of hc streams into one embedding
GGML_API struct ggml_tensor * ggml_ds4_hc_out(
struct ggml_context * ctx,
struct ggml_tensor * mix,
struct ggml_tensor * base,
struct ggml_tensor * hc_state,
int n_hc,
float pre_scale);

// TODO: needs to be adapted to ggml_flash_attn_ext
GGML_API struct ggml_tensor * ggml_flash_attn_back(
struct ggml_context * ctx,
Expand Down
40 changes: 40 additions & 0 deletions server/deps/llama.cpp/ggml/rocmfp4/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# ROCmFP4

This directory implements two GGUF weight formats used by the ROCm/HIP
backend:

| GGML type | Block layout | Block size | Bits/weight |
|---|---|---:|---:|
| `Q4_0_ROCMFP4` | 32 packed 4-bit codes and one UE4M3 scale per 16 weights | 18 bytes | 4.50 |
| `Q4_0_ROCMFP4_FAST` | 32 packed 4-bit codes and one UE4M3 scale per 32 weights | 17 bytes | 4.25 |

Both layouts use the signed Codebook10 levels
`0, +/-1, +/-2, +/-3, +/-4, +/-6, +/-8, +/-10`. Scale bytes are finite
unsigned UE4M3 values; validation rejects `0x7f` and values with the sign bit
set.

## Implementation

- `rocmfp4.c` contains deterministic CPU reference quantization,
dequantization, validation, and vector-dot functions.
- `rocmfp4_hip_codebook.cuh` and `rocmfp4_hip_scale.cuh` contain device
helpers shared by the ggml HIP kernels.
- Backend dispatch is integrated in `ggml-cuda`, which is also the source tree
used by ggml's HIP build.

The quantizer selects UE4M3 scales by minimizing reconstruction error. When an
importance matrix is supplied, finite positive weights are used in the error
metric. Non-finite source values quantize to zero and non-finite or non-positive
importance weights are ignored.

Vulkan kernels are not implemented in this vendored build.

## Tests

With `DFLASH27B_TESTS=ON`:

- `test_rocmfp4` checks CPU reference round trips, validation, and imatrix
handling.
- `test_rocmfp4_hip_tail` compares HIP conversion with the CPU reference
byte-for-byte and checks output bounds for row sizes that are and are not
multiples of 256.
Loading
Loading