15 điểm bởi GN⁺ 2025-02-22 | 1 bình luận | Chia sẻ qua WhatsApp
  • GPU là bộ xử lý song song quy mô lớn với hàng nghìn lõi, được thiết kế để xử lý nhiều tác vụ cùng lúc
  • CPU vượt trội trong các tác vụ phức tạp và tuần tự, nhưng số lượng tác vụ có thể xử lý cùng một lúc bị hạn chế
  • Ngược lại, GPU có thế mạnh trong việc xử lý nhanh khối lượng dữ liệu lớn bằng cách xử lý tác vụ song song thông qua hàng nghìn luồng
  • Ví dụ, GPU NVIDIA RTX 4090 có 16.384 lõi CUDA, so với 16~24 lõi của CPU cao cấp
  • Mỗi lõi GPU chậm hơn lõi CPU, nhưng nhờ xử lý song song với số lượng lõi rất lớn, GPU phù hợp cho các phép tính quy mô lớn như toán ma trận

CUDA và Python

  • CUDA (Compute Unified Device Architecture) của NVIDIA là một nền tảng đồng thời là phần mở rộng cho C++ cho phép viết chương trình chạy trên GPU
  • CUDA cung cấp mô hình lập trình và API để nhà phát triển có thể viết mã chạy trực tiếp trên GPU
  • Nhờ đó, có thể offload các tác vụ có khả năng xử lý song song từ CPU sang GPU để cải thiện hiệu năng
  • Lập trình viên Python có thể tận dụng tăng tốc GPU bằng các công cụ như Numba
  • Numba là một trình biên dịch Python có thể biên dịch mã Python để chạy trên GPU hỗ trợ CUDA
  • Nhờ đó, lập trình viên Python có thể dễ dàng bắt đầu với điện toán tăng tốc bằng GPU chỉ với lượng tối thiểu cú pháp và thuật ngữ mới
  • CUDA Python cung cấp các wrapper Cython/Python cho API driver và runtime của CUDA để lập trình viên Python có thể khai thác điện toán song song trên GPU
  • CUDA Python có thể được cài đặt thông qua PIP và Conda

Cấu trúc luồng và block trong CUDA

  • Trong CUDA, kernel là hàm chạy trên GPU; khi thực thi kernel, hàng trăm hoặc hàng nghìn luồng song song sẽ chạy đồng thời để xử lý dữ liệu khác nhau
  • Mô hình này được gọi là mô hình SIMT (Single-Instruction Multiple-Thread)
  • Các luồng được tổ chức thành warp (nhóm 32 luồng), và các warp được nhóm thành block
  • Mỗi block chạy trên một streaming multiprocessor (SM), và SM có tài nguyên hạn chế như thanh ghi, bộ nhớ dùng chung, v.v.
  • Kích thước block ảnh hưởng đến việc phân bổ các tài nguyên này và số lượng warp có thể chạy đồng thời (occupancy)
  • Có thể tận dụng hiệu quả tài nguyên GPU bằng cách thiết lập phù hợp số lượng và kích thước của các thread block

Quản lý bộ nhớ và tối ưu hóa

  • Trong lập trình CUDA, cần thực hiện tường minh việc quản lý bộ nhớ giữa CPU (host) và GPU (device)
  • Luồng xử lý điển hình như sau:
    • Cấp phát bộ nhớ GPU (cudaMalloc)
    • Sao chép dữ liệu từ host sang device (cudaMemcpy)
    • Thực thi kernel
    • Sao chép kết quả từ device về host (cudaMemcpy)
    • Giải phóng bộ nhớ GPU (cudaFree)
  • Bộ nhớ dùng chung là bộ nhớ on-chip cho phép các luồng trong cùng block chia sẻ dữ liệu nhanh chóng, từ đó cải thiện tốc độ truy cập bộ nhớ
  • Đồng bộ giữa các luồng được triển khai bằng __syncthreads(), nhờ đó có thể tránh race condition

Kernel CUDA tùy chỉnh cho LLM

  • Trong các tác vụ với mô hình ngôn ngữ lớn (LLM), các kernel CUDA tùy chỉnh đang được phát triển để gộp nhiều phép toán vào một kernel nhằm giảm overhead bộ nhớ và tăng hiệu quả
  • Ví dụ, FlashAttention tối ưu self-attention của Transformer bằng cách giảm số lần đọc và ghi bộ nhớ, từ đó cải thiện đáng kể hiệu quả
  • FlashAttention tận dụng bộ nhớ dùng chung để chia phép tính theo tile, nhờ đó đạt hiệu quả cao ngay cả với chuỗi dài
  • Các tối ưu hóa như vậy có thể giải quyết bài toán băng thông bộ nhớ trở thành nút thắt cổ chai trong deep learning

So sánh giữa triển khai PyTorch và CUDA

  • Trong PyTorch, có thể dễ dàng thực hiện các phép toán trên GPU thông qua mức trừu tượng cao
  • Ví dụ, phép cộng hai vector có thể được triển khai rất đơn giản như sau:
import torch  
  
# Tạo hai vector lớn trên GPU  
a = torch.rand(1000000, device='cuda')  
b = torch.rand(1000000, device='cuda')  
  
# Cộng theo từng phần tử  
c = a + b  
  • Tuy nhiên, khi cần tối ưu hiệu năng, có thể trực tiếp sử dụng CUDA để viết kernel tùy chỉnh
  • Khi dùng CUDA, có thể tinh chỉnh chi tiết mẫu truy cập bộ nhớ, cấu hình luồng, cách tận dụng bộ nhớ dùng chung, v.v. để tối đa hóa hiệu năng
  • Chẳng hạn, triển khai CUDA của FlashAttention tối ưu truy cập bộ nhớ và chia phép tính theo tile trong bộ nhớ dùng chung để cải thiện hiệu năng
  • Các tối ưu hóa mức thấp như vậy có thể đạt hiệu năng cao hơn so với triển khai mức cao của PyTorch

Kết luận

  • Tận dụng khả năng xử lý song song của GPU giúp thực hiện hiệu quả việc xử lý dữ liệu quy mô lớn và các phép tính phức tạp
  • CUDA là nền tảng giúp khai thác tối đa hiệu năng của GPU, và lập trình viên Python cũng có thể hưởng lợi từ CUDA thông qua các công cụ như Numba
  • Hiểu về cấu trúc luồng và block, cũng như các kỹ thuật quản lý bộ nhớ trong CUDA, sẽ giúp lập trình GPU hiệu quả hơn
  • Đặc biệt, trong các lĩnh vực như deep learning, có thể tối đa hóa hiệu năng bằng cách viết kernel CUDA tùy chỉnh
  • Ngay cả khi sử dụng các framework mức cao như PyTorch, vẫn có thể theo đuổi hiệu năng cao hơn bằng các tối ưu hóa CUDA mức thấp khi cần thiết

1 bình luận

 
GN⁺ 2025-02-22
Ý kiến trên Hacker News
  • Câu hỏi hơi ngớ ngẩn: với tư cách là một kỹ sư, liệu có thể đào sâu vào mức thấp của CUDA hay kiến trúc GPU mà không cần học khía cạnh toán học của AI không? Nếu có thì nên bắt đầu thế nào? Có vẻ như cần phải học về tối ưu hóa và lý do GPU được dùng cho các phép tính cụ thể

    • Câu hỏi song song: khi làm kỹ sư dữ liệu, mình luôn thắc mắc liệu có thể bước vào MLE hay mảng data engineering cho AI mà không cần biết AI/ML không. Mình từng nghĩ chỉ cần hiểu hình dạng của dữ liệu là đủ, nhưng mọi mô tả công việc MLE mình từng thấy đều yêu cầu nền tảng AI
  • Bài viết rất xuất sắc. Các câu hỏi nhanh nội tuyến (QnA) có vẻ như do AI tạo ra cực kỳ hữu ích để kiểm tra mức độ hiểu bài. Ước gì mọi tutorial đều có tính năng này

  • Mình tò mò không biết mọi tutorial về CUDA có đều nhắm đến AI hay không, hay cũng có những cái dành cho tính toán khoa học nói chung chẳng hạn. Có vẻ sẽ rất thú vị nếu thử những thứ như luồng không khí trên cánh máy bay cho high-performance computing

  • Cảm ơn vì đã chia sẻ, mình rất thích đọc bài này. Có một câu hỏi liên quan: mình muốn biết liệu có ai có góc nhìn nào về cách DeepSeek vượt qua CUDA để làm cho việc chạy hiệu quả hơn không

    • Mình luôn ngạc nhiên khi một thư viện cốt lõi như CUDA, đã được phát triển trong thời gian rất dài, vẫn còn chỗ để cải thiện. Đặc biệt là đến mức một nhóm nhà phát triển mới có thể tự lấp khoảng trống đó
  • Jensen cho thì Guido lấy lại

  • Cuốn sách này: "Programming Massively Parallel Processors" có vẻ được thiết kế riêng cho những người chuyển từ kiến trúc CPU sang GPU

  • Ngoài ra hãy xem https://github.com/rust-gpu/rust-gpuhttps://github.com/rust-gpu/rust-cuda

  • Liên kết liên quan: https://sakana.ai/ai-cuda-engineer/https://reddit.com/r/MachineLearning/…

  • Mình tò mò liệu có ai có ý tưởng gì về điều gì đã thay đổi gần đây để các mô phỏng trước đây chỉ có thể chạy trên CPU giờ đây có thể được thực hiện trọn vẹn trên GPU (ví dụ: isaac sim)

  • Vì đây là nội dung trên website của PySpur, mình tò mò không biết có ai có kinh nghiệm với các công cụ UI cho AI agent như PySpur và n8n không. Mình đang tìm thứ gì đó có thể hữu ích để prototype vài ý tưởng cho vui. Vì sẽ phải self-host ($), mình ưu tiên thứ gì đó tương đối dễ cấu hình như Open Hands