OpenArchLabOpen Architecture — From Models to Systems

D · GPU engineering

Viết kernel với tư duy dữ liệu và tính toán song song

Cách lập trình song song trên GPU bằng CUDA hoặc Triton để chia khối dữ liệu, tận dụng bộ nhớ đệm trên chip và tối ưu băng thông.

LESSON ID cuda GROUP Kiến trúc Inference
Mục lục bài học

1Định nghĩa

Lập trình kernel bằng CUDA hoặc Triton là việc viết các hàm tính toán chạy trực tiếp trên hàng nghìn nhân của GPU khi các toán tử có sẵn của framework chưa đủ nhanh hoặc tốn quá nhiều lượt đọc/ghi bộ nhớ.

Trong khi CUDA cho phép điều khiển chi tiết từng luồng (thread) và khối luồng (thread block) ở mức C++, Triton giúp kỹ sư viết mã theo từng khối mảng (tile/block) bằng Python và tự động hóa phần lớn việc sắp xếp bộ nhớ. Dù dùng công cụ nào, bài toán cốt lõi vẫn là chia tensor thành các ô vừa với bộ nhớ đệm trên chip (SRAM/shared memory), tính toán song song và hạn chế tối đa số lần truy cập bộ nhớ HBM.

Ví dụ đời thường: Viết kernel bằng CUDA/Triton giống như việc chia một bức tường lớn thành từng ô gạch để hàng trăm người thợ cùng sơn một lúc. Thay vì mỗi người thợ cứ quét một nét cọ lại phải chạy ra tận kho chính (HBM) lấy sơn, mỗi nhóm thợ xách luôn một xô sơn nhỏ đặt ngay cạnh giàn giáo của mình (SRAM trên chip) để sơn liền mạch hết cả ô tường rồi mới đổi chỗ.

2Luồng

Sơ đồ luồng (4 bước)
  1. Định nghĩa phép toán reference

    Có shapes và dtype yêu cầu.

  2. Chia dữ liệu thành tiles

    Gán công việc và chọn layout.

  3. Tính trong kernel

    Đọc, tái dùng và ghi dữ liệu.

  4. Kiểm tra và profile

    So sai số, race và latency nhiều shapes.

Mã Mermaid
flowchart TD
  step1["Định nghĩa phép toán reference"]
  step2["Chia dữ liệu thành tiles"]
  step3["Tính trong kernel"]
  step4["Kiểm tra và profile"]
  step1 --> step2
  step2 --> step3
  step3 --> step4

3Giải pháp

Bắt đầu từ một kernel đúng và một baseline. Tune tile sizes, vectorization và tài nguyên gần compute dựa profiler.

Tránh tối ưu một shape rồi mặc định các shape khác tốt. Đọc đồng thời, synchronization và lifetime sai có thể tạo lỗi chỉ xuất hiện dưới tải.

4Profiling

  • Latency và memory access

    Đo runtime theo shape; tìm giao dịch bộ nhớ dư và register spills.

  • Correctness

    So reference ở nhiều kích thước, nhất là dimensions không chia hết tile.

Mẹo đo lường: ghim số liệu trên workload thật, ghi cả p50/p95/p99 thay vì chỉ trung bình, và luôn ghi lại điều kiện chạy (batch, cache, đồng thời, phần cứng) trước và sau khi tối ưu. Số đo thiếu điều kiện chạy thì không so sánh được.

5Ví dụ

Normalization của vector

Một bài kernel nhỏ có thể bắt đầu bằng tính trung bình bình phương rồi scale từng phần tử.

Ma trận kích thước lẻ

Cần mask truy cập ngoài biên; tốc độ tốt trên shape tròn không bảo đảm đúng ở shape này.

6Thuật ngữ

Compute Unified Device Architecture (CUDA)
Nền tảng lập trình và mô hình thực thi tính toán trên thiết bị NVIDIA.
Thread và thread block
Đơn vị công việc và nhóm threads có thể phối hợp theo mô hình thực thi của thiết bị.
Coalesced memory access
Cách nhiều threads đọc các địa chỉ thuận lợi để phần cứng gộp giao dịch bộ nhớ.
Glossary (12)
Graphics Processing Unit
Bộ xử lý đồ họa, thường dùng cho phép tính tensor song song.
Data type
Kiểu dữ liệu của tensor, quyết định cách biểu diễn số.
Tensor
Mảng số nhiều chiều, như một vector, ma trận hoặc nhóm ma trận.
Vector
Danh sách các số biểu diễn một token hoặc đặc trưng.
Kernel
Hàm tính toán chạy trên thiết bị; thường xử lý nhiều phần tử song song.
Runtime
Phần mềm quản lý việc thực thi, buffers và phụ thuộc giữa phép toán.
Mask
Quy tắc vị trí nào được nhìn nhau hoặc được tính vào loss.
Latency
Thời gian chờ để nhận một kết quả hoặc một bước kết quả.
Overhead
Chi phí phụ như điều phối, chuyển đổi hoặc phát lệnh ngoài phép tính chính.
Host
Phần chương trình điều khiển thiết bị, thường chạy trên bộ xử lý trung tâm.
Baseline
Cấu hình hoặc kết quả gốc dùng làm mốc so sánh.
Tensor shape
Kích thước các chiều của tensor; ảnh hưởng layout, kernel và memory.

7Bài liên quan

8Nguồn