- GPU: NVIDIA RTX PRO 2000 Blackwell x7 (16GB x7)
- Driver: 595.71.05
- CUDA: 13.2 (nvcc 13.2.78)
- P2P: 全ペア
cudaDeviceCanAccessPeer=YES、cudaMemcpyPeer動作確認済み - OS: Linux
- pip 版
nvidia-nccl-cu13をリンク NCCL_HOMEを~/.local/lib/python3.14/site-packages/nvidia/ncclに設定libnccl.soのシンボリックリンクを作成
#include <nccl.h>g_pp_nccl_comms[7]/g_pp_nccl_readyncclCommInitAllで 7GPU communicator を一括初期化ds4_gpu_pp_p2p_copy_ptrに NCCLncclSend/ncclRecvpath を追加DS4_CUDA_PP_NCCL=1で有効化
問題: ncclGroupEnd/cudaStreamSynchronize でデッドロックする可能性あり。現状は DS4_CUDA_PP_NCCL なしでテスト中(cudaMemcpyPeer fallback を使用)。
- 各 GPU に担当 layer の KV cache tensor を新規アロケート
layer_raw_cachelayer_attn_comp_cachelayer_attn_state_kvlayer_attn_state_scorelayer_index_comp_cachelayer_index_state_kvlayer_index_state_score
- 元の実装では
ref->layer_raw_cache[il]のポインタをそのままコピーしていた(GPU0 のメモリを参照)
g_pp_graphsallocate 後に、GPU0 の KV cache から各 GPU の KV cache へds4_gpu_pp_p2p_copy_ptrでコピー- コピー後
ds4_gpu_synchronize()
metal_graph_encode_token_raw_swa_ppを新設- フロー:
- GPU0 で embed token
- for gpu in 0..6:
cudaSetDevice(gpu)- 担当 layer を
metal_graph_encode_decode_layerで実行 cur_hc <-> after_ffn_hcswap- P2P copy
after_ffn_hc-> next GPUcur_hc
- 最後の GPU から GPU0 へ final
after_ffn_hcをコピー - GPU0 で
metal_graph_encode_output_head
cuda_model_rangeにint deviceフィールドを追加ds4_gpu_cache_model_range_forceでcudaGetDevice(¤t_dev)を記録cuda_model_range_ptrで exact match / linear search 時にcurrent_devと一致するエントリを優先- 理由: 同じ
offsetを複数 GPU で登録するとg_model_range_by_offsetが上書きされ、GPU0 の kernel が GPU6 の weight pointer を取得して illegal memory access していた
ds4_gpu_debug_tensor_ptrを追加(cudaPointerGetAttributesで device/type/bytes を確認)
| 設定 | generation t/s | 備考 |
|---|---|---|
| Baseline (PPなし) | 3.59 t/s | 正答 |
| PP 旧(g_pp_active のみ) | 16.27 t/s | ❌ illegal memory access |
| PP 新(per-GPU graph + deviceフィルタ) | 28.58 t/s | ❌ rms_norm_plain illegal memory access |
→ 28.58 t/s は 30TPS 目標の 95% 達成。あとはクラッシュを直せば夢の 30TPS 目前。
ds4: PP KV cache copy done
ds4: g0->cur_hc ptr=0x7e6d539a4a00 device=0 type=2 bytes=65536
ds4: g0->flat_hc ptr=0x7e6d539b4a00 device=0 type=2 bytes=65536
ds4: CUDA rms_norm_plain launch failed: an illegal memory access was encountered
ds4: CUDA synchronize failed: an illegal memory access was encountered
embed_token_hc_kernelは成功(ds4_gpu_synchronize()後エラーなし)g0->cur_hc/g0->flat_hcは両方device=0(GPU0)、type=2(device memory)で正しいrms_norm_plain_kernelはout->ptr/x->ptrのみをアクセスする単純な RMS norm kernel- エラーは
cudaGetLastError()で検出(kernel launch 時ではなく実行時の illegal memory access)
ds4_gpu_initはcudaSetDevice(0)してg_cuda_decode_streamを作成ds4_decode_stream()は GPU0 の場合g_cuda_decode_streamを返すrms_norm_plain_kernelはds4_decode_stream()で指定されたストリームで実行g0->cur_hc/g0->flat_hcのポインタはcudaPointerGetAttributesで検証済み(GPU0 device memory)ds4_gpu_rms_norm_plain_tensorの引数チェックも通過(bytes >= n * sizeof(float))
-
なぜ
rms_norm_plain_kernelが illegal memory access を起こすのか?g_cuda_decode_streamが実際に GPU0 に関連付けられているか確認cudaStreamGetFlagsやcudaStreamQueryでストリームの状態確認rms_norm_plain_kernelの launch パラメータ(grid/block/shared)に問題がないか再確認cudaMemsetでg0->cur_hc/g0->flat_hcを 0 埋めしてから kernel を実行し、同じエラーになるか確認(データ依存性の排除)
-
cuda_model_range_ptrの device フィルタが不完全な可能性g_model_range_by_offsetはunordered_map<uint64_t, size_t>で、最後に登録されたインデックスを保持- exact match で
r.device == current_devが一致しない場合、linear search にフォールバック - linear search で
fallbackを返す場合、そのポインタが別 GPU のものになる可能性がある fallbackを返さずにNULLを返すべきか?(PP mode では各 GPU に必ずキャッシュがあるはず)
-
ds4_gpu_release_weight_cache_for_pp()の影響cuda_model_range_release_all()でg_model_rangesをクリアcuda_q8_f16_cache_release_all()でg_q8_f16_rangesをクリア- これらが GPU0 のみを対象としていて、他の GPU のキャッシュが正しく構築されているか確認
-
metal_graph_encode_decode_layer内の他の kernelrms_norm_plainより前にds4_gpu_hc_split_weighted_sum_norm_tensorなどが実行される可能性- 実際には
rms_norm_plainが最初の kernel のはずだが、確認が必要
-
ds4_gpu_flush_commands()/ds4_gpu_end_commands()の呼び出しタイミングmetal_graph_encode_token_raw_swa_ppではds4_gpu_flush_commands()を呼んでいない- 各 GPU の default stream に kernel が積まれているが、同期が不完全な可能性
- ブランチ: main
- 変更ファイル: Makefile, ds4.c, ds4_cuda.cu, ds4_gpu.h
- 未追跡: scripts/ (bench_30tps.sh)
DS4_CUDA_PP_NCCLは現状デッドロックの可能性があるため無効化してテスト中cudaMemcpyPeerfallback で十分な速度が出ている(28.58 t/s)- あとは 1つの illegal memory access を潰せば、正答性確認 + 30TPS 達成が目前