2 คะแนน โดย GN⁺ 2025-02-27 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • DeepGEMM เป็นไลบรารีเคอร์เนล tensor core ประสิทธิภาพสูงที่รวม GEMM, fused MoE, MQA scoring, HyperConnection และองค์ประกอบการคำนวณหลักอื่นๆ ของ LLM สมัยใหม่ไว้ในโค้ดเบส CUDA เดียว
  • เคอร์เนลทั้งหมดถูกคอมไพล์ขณะรันไทม์เป็น โมดูล JIT แบบเบา ไม่ต้องคอมไพล์ CUDA ระหว่างติดตั้ง และต้องการ C++20, CUDA Toolkit, PyTorch และ CUTLASS 4.0 ขึ้นไป
  • แม้จะใช้แนวคิดบางส่วนจาก CUTLASS และ CuTe แต่ไม่ได้พึ่งพาเทมเพลตหรือโครงสร้างพีชคณิตอย่างหนัก และออกแบบมาให้เข้าถึงการเรียนรู้เรื่อง การปรับแต่งเคอร์เนลบน NVIDIA GPU ได้ง่าย ผ่านชุดฟังก์ชันเคอร์เนลหลักจำนวนจำกัด
  • ขอบเขตการรองรับครอบคลุม FP8, FP4, BF16 GEMM, grouped GEMM, เคอร์เนล MQA logits สำหรับ DeepSeek v3.2 และ Mega MoE ที่ซ้อนทับการสื่อสารกับการคำนวณ โดยมีข้อจำกัดด้าน memory layout ต่างกันระหว่าง SM90 และ SM100
  • แม้จะออกแบบให้มีน้ำหนักเบา แต่ยังมุ่งเป้าประสิทธิภาพที่เทียบเท่าหรือสูงกว่าไลบรารีที่จูนโดยผู้เชี่ยวชาญใน matrix shape หลากหลายแบบ และมีอัปเดตที่ทำได้สูงสุดถึง 1550 TFLOPS บน H800

วัตถุประสงค์และการออกแบบของ DeepGEMM

  • DeepGEMM เป็นไลบรารีเคอร์เนล tensor core ที่รวมองค์ประกอบการคำนวณหลักที่ใช้ในโมเดลภาษาขนาดใหญ่รุ่นใหม่ไว้ในโค้ดเบส CUDA เดียว
    • GEMM: FP8, FP4, BF16
    • fused MoE ที่ซ้อนทับการสื่อสาร: Mega MoE
    • MQA scoring สำหรับ lightning indexer
    • HyperConnection(HC)
  • เคอร์เนลทั้งหมดถูกคอมไพล์ขณะรันไทม์เป็น Just-In-Time(JIT) โมดูลแบบเบา
    • ไม่ต้องคอมไพล์ CUDA ในขั้นตอนติดตั้ง
  • ใช้แนวคิดบางส่วนจาก CUTLASS และ CuTe
    • แต่ไม่ได้พึ่งพาเทมเพลตหนักๆ หรือโครงสร้างพีชคณิตมากนัก
    • จำกัดจำนวนฟังก์ชันเคอร์เนลหลักเพื่อให้โค้ดเบสเรียบง่าย
  • แม้จะเป็นการออกแบบแบบเบา แต่ระบุว่าสามารถให้ ประสิทธิภาพเทียบเท่าหรือสูงกว่า ไลบรารีที่จูนโดยผู้เชี่ยวชาญใน matrix shape หลายแบบ

อัปเดตสำคัญ

  • อัปเดตวันที่ 16 เมษายน 2026 เพิ่ม Mega MoE, FP8xFP4 GEMM, FP4 Indexer, PDL และ JIT compile ที่เร็วขึ้น
    • รายละเอียดดูที่ #304
    • เบนช์มาร์ก Mega MoE อยู่ที่ #316
  • อัปเดตวันที่ 28 กันยายน 2025 เพิ่มเคอร์เนล scoring แบบ weighted ReLU MQA logits สำหรับ lightning indexer ของ DeepSeek v3.2
    • รายละเอียดดูที่ #200
  • อัปเดตวันที่ 20 กรกฎาคม 2025 รองรับทั้ง SM90 และ SM100 และรีแฟกเตอร์ทั้งหมดเป็น JIT CPP โมดูลที่มี CPU overhead ต่ำ
    • NVRTC และการปรับแต่ง SASS หลังคอมไพล์ถูกปิดใช้งาน
    • ระบุว่าจะรองรับ NVRTC ในภายหลัง
    • เนื่องจาก NVCC 12.9 ทำ FFMA interleaving ให้อัตโนมัติแล้ว จึงไม่รองรับการปรับแต่งหลังคอมไพล์อีกต่อไป
    • รายละเอียดดูที่ #112
  • อัปเดตวันที่ 14 พฤษภาคม 2025 เพิ่มเคอร์เนล weight gradient สำหรับ dense และ MoE backward
    • รายละเอียดดูที่ #95
  • อัปเดตวันที่ 7 พฤษภาคม 2025 รองรับ NVRTC และให้ ความเร็วคอมไพล์สูงสุด 10 เท่า
    • เปิดใช้ได้ด้วย DG_JIT_USE_NVRTC=1
    • อาจมีประสิทธิภาพลดลงในบางกรณี
    • รายละเอียดดูที่ #94
  • อัปเดตวันที่ 18 เมษายน 2025 ทำได้สูงสุด 1550 TFLOPS บน H800
    • รายการที่เกี่ยวข้องคือ #74, #78, #81, #86, 340d988

ข้อกำหนดและขั้นตอนการติดตั้ง

  • สภาพแวดล้อมการรันต้องใช้ GPU สถาปัตยกรรม NVIDIA SM90 หรือ SM100
  • ข้อกำหนดซอฟต์แวร์มีดังนี้
    • Python 3.8 ขึ้นไป
    • คอมไพเลอร์ที่รองรับ C++20
    • CUDA Toolkit
      • SM90: CUDA 12.3 ขึ้นไป
      • เพื่อประสิทธิภาพสูงสุด แนะนำอย่างยิ่งให้ใช้ CUDA 12.9 ขึ้นไป
      • SM100: CUDA 12.9 ขึ้นไป
    • PyTorch 2.1 ขึ้นไป
    • CUTLASS 4.0 ขึ้นไป
    • ไลบรารี {fmt}
  • ในสภาพแวดล้อมการพัฒนา ให้ clone รีโพซิทอรีพร้อม submodule แล้วใช้ develop.sh เพื่อเชื่อม include ที่จำเป็นและ build CPP JIT โมดูล
  • การติดตั้งทำโดยรัน install.sh แล้ว import deep_gemm ในโปรเจกต์ Python

อินเทอร์เฟซ GEMM และข้อจำกัดของเลย์เอาต์

  • กฎการตั้งชื่อเคอร์เนล GEMM ของ DeepGEMM คือ D = C + A @ B
  • shape layout ของอินพุตอิงตาม NT
    • fp8_gemm_nt จะทำ D = C + A @ B.T
  • การอิมพลีเมนต์บน SM90 รองรับเฉพาะ NT memory layout
    • ตรงกับชุด row-major, col-major
  • การอิมพลีเมนต์บน SM100 รองรับ memory layout ครบทั้ง NT, TN, NN, TT
  • ทั้งสองสถาปัตยกรรมกำหนดให้ LHS scaling factor ต้องอยู่ในเลย์เอาต์ที่จัดแนวสำหรับ TMA และถูก transpose แล้ว
    • SM90 ต้องใช้ scaling factor รูปแบบ FP32
    • SM100 ต้องใช้รูปแบบ packed UE8M0 โดย pack UE8M0 4 ค่าไว้ใน torch.int หนึ่งตัว
  • งานอย่างการ transpose อินพุตหรือการ cast เป็น FP8 ผู้ใช้ต้องจัดการเองแยกต่างหาก
    • ไลบรารีมีฟังก์ชันยูทิลิตี PyTorch แบบง่ายให้ แต่ประสิทธิภาพอาจช้า
    • โฟกัสหลักคือ การปรับแต่งเคอร์เนล GEMM

Dense และ Grouped GEMM

  • FP8 GEMM แบบ non-grouped พื้นฐานใช้ฟังก์ชัน fp8_gemm_{nt, nn, tn, tt}
  • grouped GEMM แบบ contiguous layout ต่างจาก grouped GEMM แบบดั้งเดิมของ CUTLASS ตรงที่ทำ การจัดกลุ่มเฉพาะแกน M
    • N และ K ต้องคงที่
    • ออกแบบมาสำหรับกรณีที่ experts ในโมเดล MoE ใช้ shape เดียวกัน
  • ใน training forward pass หรือ inference prefilling จำนวนโทเค็นที่แต่ละ expert ประมวลผลอาจต่างกัน
    • การนำโทเค็นเหล่านี้มาต่อกันเป็น tensor เดียวเรียกว่า contiguous layout
    • แต่ละ expert segment ต้องจัดแนวตาม GEMM M block size
    • ตรวจสอบเกณฑ์การจัดแนวได้ด้วย get_mk_alignment_for_contiguous_layout()
  • ยังมี K-axis grouped API สำหรับ MoE weight backward ด้วย
    • M และ N ต้องคงที่
    • ฟังก์ชันที่เกี่ยวข้องคือ k_grouped_fp8_gemm_tn_contiguous
  • ในขั้น inference decoding หากเปิด CUDA graph และ CPU ไม่ทราบจำนวนโทเค็นต่อ expert จะรองรับ masked grouped GEMM
    • หากให้ mask tensor เคอร์เนลจะคำนวณเฉพาะบริเวณที่ถูกต้อง
    • ฟังก์ชันคือ m_grouped_fp8_gemm_nt_masked
    • มีตัวอย่างที่ใช้อินพุตจากเอาต์พุตของ low-latency kernel ใน DeepEP

เคอร์เนล MQA สำหรับ DeepSeek v3.2 Indexer

  • ตระกูลเคอร์เนล MQA ของ V3.2 มีทั้งเวอร์ชัน non-paged และ paged
    • non-paged สำหรับ prefilling
    • paged สำหรับ decoding
  • fp8_mqa_logits รับอินพุต 6 ตัว
    • q: E4M3 tensor, shape [seq_len, num_heads, head_dim]
    • kv: E4M3 tensor และ float scaling factor
      • tensor shape คือ [seq_len_kv, head_dim]
      • scaling factor shape คือ [seq_len_kv]
    • weights: float tensor, shape [seq_len, num_heads]
    • cu_seq_len_k_start, cu_seq_len_k_end: int tensor, shape [seq_len]
    • clean_logits: จะล้าง logits ที่ไม่ได้เติมค่าให้เป็น -inf หรือไม่
  • tensor เอาต์พุตมี shape [seq_len, seq_len_kv] และแทน token-to-token logits
  • สำหรับแต่ละ q token i จะวนผ่าน kv token j ตั้งแต่ cu_seq_len_k_start[i] จนก่อน cu_seq_len_k_end[i]
    • คูณ kv_j ด้วย scaling factor
    • คำนวณค่าราย head ด้วย q[i, :, :] @ kv_j
    • ใช้ ReLU จากนั้นคูณ weights[i, :] และรวมผลเพื่อสร้าง scalar logit
  • ฟังก์ชันเวอร์ชัน paged คือ fp8_paged_mqa_logits

Mega MoE

  • Mega MoE รวมหลายขั้นของ MoE เข้าเป็น mega-kernel เดียว
    • EP dispatch
    • linear 1, FP8xFP4
    • SwiGLU
    • linear 2, FP8xFP4
    • EP combine
  • Mega MoE ทำ overlap ระหว่างการสื่อสารผ่าน NVLink กับการคำนวณ tensor core
  • การรันต้องใช้การเปิดหลายโปรเซสพร้อม symmetric memory
  • ลำดับการใช้งานมีดังนี้
    • จัดสรร symmetric memory buffer ด้วย deep_gemm.get_symm_buffer_for_mega_moe
      • ต้องใช้ PyTorch 2.9 ขึ้นไป
    • แปลง weight ให้อยู่ในเลย์เอาต์ที่ต้องการ รวมถึง FP4 และ UE8M0 SF ด้วย deep_gemm.transform_weights_for_mega_moe
    • ก่อนเรียกใช้ ให้คัดลอกอินพุต, scaling factor, top-k index และ top-k weight ลงใน buffer
    • รัน fused mega MoE kernel ด้วย deep_gemm.fp8_fp4_mega_moe
  • ตัวอย่างการตั้งค่า multi-process แบบเต็มและการเบนช์มาร์กอยู่ใน tests/test_mega_moe.py

ยูทิลิตีและตัวแปรสภาพแวดล้อม

  • ฟังก์ชันยูทิลิตีหลักใช้ควบคุมทรัพยากรการรัน การจัดแนว JIT compile และการแปลง scaling factor
    • deep_gemm.set_num_sms / get_num_sms: ตั้งค่าและดูจำนวน SM สูงสุดที่จะใช้
    • deep_gemm.set_tc_util / get_tc_util: ตั้งค่าและดูค่า utilization ratio โดยประมาณของ tensor core
    • deep_gemm.set_pdl / get_pdl: เปิดและปิดใช้งาน Programmatic Dependent Launch(PDL)
    • deep_gemm.set_mk_alignment_for_contiguous_layout / get_mk_alignment_for_contiguous_layout: ตั้งค่าและดู group-level M/K alignment ของ contiguous layout
    • deep_gemm.transform_sf_into_required_layout: แปลง scaling factor ให้อยู่ในเลย์เอาต์ที่ต้องการ
    • deep_gemm.get_tma_aligned_size: ดูขนาด TMA alignment ที่ต้องการ
  • ตัวแปรสภาพแวดล้อมที่เกี่ยวกับ JIT ใช้ควบคุมการแสดงผลดีบัก ตำแหน่งแคช การเลือกคอมไพเลอร์ และตัวเลือกการโปรไฟล์
    • DG_JIT_DEBUG: แสดงข้อมูลดีบักของ JIT
    • DG_PRINT_CONFIGS: แสดง config ที่เลือกตามแต่ละ shape
    • DG_JIT_CACHE_DIR: ไดเรกทอรีแคชของเคอร์เนลที่คอมไพล์แล้ว ค่าเริ่มต้นคือ $HOME/.deep_gemm
    • DG_JIT_USE_NVRTC: ใช้ NVRTC แทน NVCC คอมไพล์ได้เร็วขึ้นแต่บางกรณีอาจให้ประสิทธิภาพต่ำกว่า
    • DG_JIT_NVCC_COMPILER: พาธของคอมไพเลอร์ NVCC
    • DG_JIT_CPP_STANDARD: เวอร์ชันมาตรฐาน C++ ค่าเริ่มต้นคือ 20
  • ยังมีตัวแปรสภาพแวดล้อมสำหรับดีบักและโปรไฟล์ด้วย
    • DG_JIT_DUMP_ASM, DG_JIT_DUMP_PTX, DG_JIT_DUMP_SASS: dump เอาต์พุต PTX และ SASS
    • DG_JIT_WITH_LINEINFO: ใส่ข้อมูล source line สำหรับเครื่องมือโปรไฟล์
    • DG_COMM_KERNEL_DEBUG: กำหนดค่า symmetric buffer เป็น 0 ก่อนเรียก Mega MoE
    • DG_USE_NVIDIA_TOOLS: ข้าม profiling ภายในเมื่อรันเครื่องมือ NVIDIA ภายนอก
  • ตัวเลือกการ build ใช้ควบคุมการติดตั้งและวิธีโหลดเคอร์เนล
    • DG_SKIP_CUDA_BUILD: ข้ามการ build CUDA extension ระหว่างติดตั้ง
    • DG_FORCE_BUILD: บังคับ build แบบโลคัลแทนการดาวน์โหลด pre-built wheel
    • DG_JIT_USE_RUNTIME_API: ใช้ CUDA Runtime API สำหรับโหลดเคอร์เนล ต้องใช้ CUDA runtime 12.8 ขึ้นไป

ไลเซนส์และการอ้างอิง

  • รีโพซิทอรี DeepGEMM เผยแพร่ภายใต้ MIT License
  • โปรเจกต์ระบุว่าได้รับแรงบันดาลใจจาก CUTLASS
  • ชื่อหัวข้อสำหรับการอ้างอิงคือ DeepGEMM: clean and efficient BLAS kernel library on GPU

1 ความคิดเห็น

 
GN⁺ 2025-02-27
ความคิดเห็นจาก Hacker News
  • การสลับ FFMA SASS แบบ interleaving ดูน่าทึ่งมาก
    หลังจากเห็นว่าประสิทธิภาพของเคอร์เนล CUTLASS FP8 ดีขึ้นระหว่าง NVCC 12.2 กับ 12.3 จึงลองเทียบ SASS ที่คอมไพล์แล้ว และพบว่ามีบิตหนึ่งในหลายคำสั่ง FADD ถูกพลิกเป็นรูปแบบ interleaving และจากการอ้างอิงอิมพลีเมนเทชัน CUDA assembler แบบโอเพนซอร์สก็ดูเหมือนจะพบว่าบิตนั้นคือ yield bit ที่ทำให้วาร์ปปัจจุบันยอมปล่อยให้วาร์ปอื่นทำงานแทน
    ผู้แสดงความเห็นยังสร้างสคริปต์ที่ใช้สิ่งนี้เพื่อแก้คำสั่ง FFMA ในไบนารีที่คอมไพล์แล้ว และไม่เพียงพลิก yield bit เท่านั้น แต่ยังพลิก reuse bit ด้วย เพราะเมื่อวาร์ปยอมหลีกทางก็จะไม่สามารถใช้ register reuse ได้ จึงทำให้คำสั่ง MMA กับคำสั่ง FFMA ที่ถูก promote ซ้อนทับกันได้ดีขึ้นใน fine-grained scaling FP8 GEMM และในบางกรณีเพิ่มประสิทธิภาพได้มากกว่า 10% ซึ่งน่าประทับใจมาก

    • จากที่เคยอ่านที่อื่นมา วิธีแบบนี้ถือว่าเป็นเรื่องปกติในการ ปรับแต่งประสิทธิภาพงานเมทริกซ์ ที่ซีเรียสเรื่องความเร็ว
      เพียงแต่สำหรับปัญหาเฉพาะนี้ ดูเหมือนว่าบริษัท AI อื่น ๆ ยังไม่รู้สึกว่าจำเป็นต้องทำ และสุดท้ายทุกเจ้าก็น่าจะไปถึงจุดคล้าย ๆ กัน
    • Scott Gray เคยค้นพบเรื่องแบบนี้และมากกว่านี้บน Maxwell ตั้งแต่ปี 2015 แล้ว และหลังจากนั้นก็มีคนอีกหลายคนทำเรื่องนี้กันมาเยอะ
  • กรณีนี้แสดงให้เห็นชัดว่า คอมไพเลอร์ ในปัจจุบันยังห่างไกลแค่ไหนจากการดึงสมรรถนะฮาร์ดแวร์ออกมาด้วยโค้ดระดับสูงเพียงอย่างเดียว
    เลยอดสงสัยไม่ได้ว่าถ้าจะให้เทคนิคคอมไพเลอร์แบบดั้งเดิมหรือเอเจนต์ปรับแต่งที่ใช้ AI สร้างผลลัพธ์แบบนี้ได้ จะต้องมีอะไรบ้าง

    • น่าจะต้องมีการลองผิดลองถูกมหาศาลภายใน ลูปป้อนกลับของ reinforcement learning
  • ตัวเลขการเพิ่มความเร็วที่รายงานนั้นเทียบกับ baseline ที่อิง CUTLASS ของตัวเอง
    เลยสงสัยว่ามีใครเปรียบเทียบประสิทธิภาพกับ cuBLAS โดยตรงหรือยัง
    เท่าที่เคยเห็น ผล GEMM ของ CUTLASS มักอยู่ในระยะราว 10% จาก cuBLAS ดังนั้นถ้าการเพิ่มขึ้น 2x~2.5x ตามที่บทความบอกยังคงอยู่จริง ก็น่าจะน่าประทับใจมาก

    • ปกติแล้วจะเลี่ยง FP8 และชอบ I8 มากกว่า แต่คำถามนี้ทำให้อยากรู้ว่า cuBLAS ทำได้ดีแค่ไหน
      อย่างแรก cuBLAS ต้องใช้ cuBLASLt extension API เพื่อจัดการงาน mixed-precision อย่าง FP8
      นอกจากนี้ ใน A x B ก็ไม่ได้รองรับคู่ชนิดข้อมูลที่ดูสมเหตุสมผลอย่าง E5M2 x E5M2 แต่รองรับ E5M2 x E4M3 แทน และบน Ampere, Hopper, Blackwell ก็ยังมีข้อจำกัดต่อเนื่อง เช่น เมทริกซ์ A ต้องอยู่ในเลย์เอาต์แบบ transpose เสมอ
      ผู้แสดงความเห็นได้นำ FP8 cuBLASLt benchmark ไปรวมไว้ในรีโพ "Less Slow C++" <https://github.com/ashvardanian/less_slow.cpp> และเพิ่มเข้าไปในรายการ benchmark ของ cuBLAS เดิมและ CUDA/PTX ที่เขียนเอง
      ตอนนี้กำลังรันบน H200 GPU ซึ่งควรให้ประสิทธิภาพเท่ากับ H100 และสำหรับอินพุตสี่เหลี่ยมจัตุรัส throughput ขึ้นไปแตะจุดสูงสุดราว 1.35 Peta-ops
      ตัวเลขคร่าว ๆ คือ 256 ได้ 2.68T/s, 512 ได้ 20.49T/s, 1024 ได้ 144.23T/s, 2048 ได้ 665.68T/s, 4096 ได้ 1.26P/s, 8192 ได้ 1.34P/s, และ 16384 ได้ 1.23P/s ซึ่งคิดเป็นราว 67% ของตัวเลขที่ NVIDIA โปรโมตสำหรับ dense GEMM <https://resources.nvidia.com/en-us-data-center-overview-mc/e...>
    • เคยได้ยินมาว่า CUTLASS ทำประสิทธิภาพได้ดีกว่า cuBLAS
      เลยคิดว่า baseline น่าจะเลือกตัวที่ดีกว่าระหว่าง cuBLAS กับ CUTLASS มาใช้
  • โอเพนซอร์สแบบนี้สะท้อนเป้าหมายของอุตสาหกรรมเรื่อง การบรรลุประสิทธิภาพ ได้ดีมาก
    แต่ผู้ที่ได้ประโยชน์จากซอฟต์แวร์นี้มากที่สุดน่าจะเป็นบริษัทใหญ่ที่ให้บริการโมเดลในสเกลมหาศาล ซึ่งเป็นคู่แข่งที่เป็นไปได้ของ DeepSeek มากกว่าจะเป็นชุมชนโอเพนซอร์สทั่วไปที่อยากเรียนรู้ ทดลอง หรือเสิร์ฟโมเดลบนฮาร์ดแวร์ฝั่งผู้บริโภค

    • เมื่อประสิทธิภาพดีขึ้น สุดท้ายก็อาจนำไปสู่ ฮาร์ดแวร์ที่ถูกลง สำหรับทุกคน รวมถึง DeepSeek เองด้วย
  • ยังไม่แน่ใจว่าการมุ่งปรับแต่งไปสู่ความแม่นยำที่ต่ำลงเรื่อย ๆ จะเป็นแนวทางที่ดีในระยะยาวหรือไม่
    มันสื่อว่าโมเดลมี ความเบาบาง อยู่มากพอสมควร ซึ่งตอนนี้อาจจริง แต่ดูเหมือนจะเป็นเพราะมีไอเดียที่ไม่ดีปะปนอยู่ในวิธีฝึก มากกว่าจะเป็นเพราะมันต้องเบาบางแบบนั้นโดยเนื้อแท้

    • ตราบใดที่ ความเบาบางที่ได้ฟรี ยังใช้ได้ ก็ใช้มันไปก่อน
      การทำให้ฝึกโมเดลที่ดีมากได้เฉพาะที่ precision สูงกว่าเป็นปัญหางานวิจัย ส่วนการฝึกและอนุมานแบบ precision ต่ำเป็นปัญหางานวิศวกรรม
      เรื่องนี้ทำกันมาตั้งแต่ยุค CNN อย่างน้อยก็ 9 ปีแล้ว และน่าจะยังทำกันต่อไปอีกหลายปี
    • เพราะ activation function ทิ้ง ช่วงไดนามิก ของเลขทศนิยมลอยตัวไปไม่น้อย จึงค่อนข้างชัดว่าการเผื่อช่วงกว้างไว้ให้บริเวณ activation ที่อิ่มตัวอยู่แล้วอาจไม่ได้มีประโยชน์นัก
  • เรื่องนี้อาจหมดความหมายลงเพราะ MXFP ซึ่งเป็น การรองรับ microscaling แบบเนทีฟ ของ Blackwell
    บน Hopper เหมือนเป็นการทำสิ่งนั้นแบบ manual ด้วยหน่วยที่หยาบกว่า แต่ใช้ค่าสเกลแบบ FP32 แทน

    • ใช่เลย
      เดโมสาธารณะคุณภาพสูงแบบนี้แสดงให้เห็นชัดว่า คูเมืองของ $NVDA อยู่ตรงไหน
      GPU แบบอเนกประสงค์มีความยืดหยุ่นสูงมาก จนสามารถโปรแกรมให้ทำงานหลายอย่างที่สมเหตุสมผลได้ แม้ผู้ขายฮาร์ดแวร์จะไม่ได้นึกถึงตั้งแต่แรก
      แต่ถ้าคาดการณ์ว่าอนาคตจะค่อย ๆ ไปสู่การรองรับด้วยฮาร์ดแวร์เฉพาะทางมากขึ้นจนพื้นที่สำหรับการปรับแต่งด้วยซอฟต์แวร์หายไป สิ่งที่เรียกว่า คูเมืองของ CUDA ก็จะพังลง
      ถ้า NVIDIA จะยังอยู่ในเกมนี้ต่อ ก็เท่ากับต้องทุบทิ้งคูเมืองของตัวเอง :p
  • ว้าว เป็น สัญญาอนุญาต MIT
    อยากเห็นบริษัทใหญ่ ๆ เปิดรับวิธีร่วมมือกันแบบโอเพนซอร์สเช่นนี้

  • ยังคงสงสัยอยู่เสมอว่าทำไมถึงมี คำสั่งที่ไม่มีเอกสารกำกับ
    ต่อให้ยังไม่เสถียรสมบูรณ์ ก็น่าจะดีกว่าถ้าเปิดให้ผู้ใช้เข้าถึงได้
    เรื่องแบบนี้ภายในองค์กรก็น่าจะมีเอกสารอยู่แล้ว แต่ไม่เข้าใจว่าทำไมถึงไม่เปิดเผย
    ความปลอดภัยที่พึ่งพาความคลุมเครือใช้ไม่ได้ผลอยู่แล้ว และคู่แข่งก็ทำวิศวกรรมย้อนกลับกันหมดอยู่ดี

    • ก็น่าจะด้วยเหตุผลคล้ายกับที่สิ่งที่เราสร้างเองก็มักมีส่วนที่ไม่ได้ทำเอกสารไว้
      อาจเป็นเพราะเวลาไม่พอ หรือไม่อยากสื่อเป็นนัยว่ารองรับฟีเจอร์ที่ยังไม่เสถียรหรือยังอยู่ในขั้นทดลอง
      ถ้าผลกระทบจำกัดอยู่แค่ทีมข้าง ๆ ก็ย่อมเปลี่ยนได้ง่ายกว่ามาก
    • สมมติฐานที่ว่า “เรื่องแบบนี้ภายในน่าจะมีเอกสารอยู่แล้ว” อาจไม่จริงตั้งแต่แรกก็ได้
      มันน่าจะมีอยู่แค่ใน เอกสารออกแบบสถาปัตยกรรม หรือเอกสารสเปกบางอย่างเท่านั้น และเอกสารแบบนั้นก็แน่นอนว่าไม่อยากแชร์กันอยู่แล้ว
  • พูดตามตรง นี่เป็นเรื่องที่เกินขอบเขตการใช้งานและความเข้าใจของผม
    ถึงอย่างนั้นก็รู้สึกขอบคุณและสดใหม่มากที่มีการแบ่งปันการค้นพบและการปรับปรุงแบบนี้เพื่อให้ทุกคนได้ประโยชน์ร่วมกัน

    • FFMA ย่อมาจาก Fused Floating-point Multiply-Add เป็นคำสั่งพื้นฐานของ GPU ที่คำนวณ D = A*B + C ในครั้งเดียว
      มันสำคัญมากสำหรับงานคูณเมทริกซ์และเวิร์กโหลดด้าน deep learning
      ใน SASS ของ NVIDIA คำสั่ง FFMA ถูกเข้ารหัสเป็นคำสั่งขนาด 64 บิตหรือ 128 บิต และมีบิตควบคุมหลายตัวที่กำหนดพฤติกรรมอย่างชัดเจน
      เมื่อมีการตั้งค่า yield bit ตัว warp scheduler จะได้รับสัญญาณว่าหลังคำสั่งนี้ warp ปัจจุบันสามารถยอมสละการรันได้ และฮาร์ดแวร์จะไปรัน warp อื่นเพื่อซ่อน latency
      GPU ได้ throughput สูงจากการทำงานขนานจำนวนมาก และเมื่อ warp หนึ่งหยุดรอ เช่น รอหน่วยความจำ warp อื่นก็สามารถเดินหน้าต่อได้
      reuse bit บอกว่า source register สามารถนำกลับมาใช้ซ้ำในโอเปอเรชันถัดไปได้หรือไม่ และถ้าตั้งค่า yield bit ไว้ ก็จำเป็นต้องปิด reuse bit
      เพราะเมื่อ warp ยอมสละการรันแล้ว warp ที่ถูกรันต่อไปอาจไม่ใช่ warp เดิม และ warp อื่นอาจทำให้สถานะของ register file เปลี่ยนไปได้ ทำให้ฮาร์ดแวร์ไม่สามารถรับประกันได้ว่าค่า register จะคงเดิมข้าม yield
      ถ้าตั้งค่า yield bit ให้กับคำสั่ง FFMA ในรูปแบบสลับกัน คอมไพเลอร์ก็จะสร้างจุด scheduling แบบชัดเจนที่เปิดโอกาสให้ warp อื่นเดินหน้าได้ และเพื่อรักษาความถูกต้องก็ต้องล้าง reuse bit ของคำสั่งนั้นไปพร้อมกัน
      การเปลี่ยนแปลงนี้ช่วยอย่างมากโดยเฉพาะกับการซ้อนทับ คำสั่ง MMA ซึ่งเป็นแกนหลักของการคูณเมทริกซ์ และ คำสั่ง FFMA สำหรับการยกระดับความแม่นยำ ที่ใช้แปลงค่า FP8 เพื่อสะสมผลด้วยความแม่นยำสูงกว่า
      โดยทั่วไป FP8 GEMM ต้องมีขั้นตอนแปลงไปเป็นความแม่นยำสูงกว่าสำหรับการสะสมผลแล้วแปลงกลับ จึงเกิด FFMA เพิ่มขึ้น ซึ่งแม้จะลดความต้องการแบนด์วิดท์หน่วยความจำได้ แต่ก็สร้างรูปแบบการคำนวณที่ซับซ้อนจากการสลับกันของโอเปอเรชันยกระดับ/ลดระดับ
      ดูเหมือนว่า “การสเกลแบบละเอียด” จะหมายถึงการจัดการความแม่นยำอย่างระมัดระวังในหลายจุดของการคำนวณ
      การปรับ yield bit ทำให้โอเปอเรชันคำนวณกับการแปลงรูปแบบข้อมูลสอดประสานกันได้ดีขึ้น จึงใช้ execution unit ของ GPU ได้อย่างมีประสิทธิภาพมากขึ้น และหากไม่มีการปรับแต่งนี้ warp scheduler อาจหาโอกาสสลับตามธรรมชาติไม่เจอ ทำให้ทรัพยากรด้านการคำนวณถูกใช้งานได้ไม่เต็มที่