Từ Zero đến GPU- Hướng dẫn xây dựng và mở rộng quy mô CUDA Kernels sẵn sàng cho sản xuất

  • 20 min read
Từ Zero đến GPU- Hướng dẫn xây dựng và mở rộng quy mô CUDA Kernels sẵn sàng cho sản xuất

Từ Zero đến GPU: Hướng dẫn Xây dựng và Mở rộng Kernel CUDA Sẵn sàng cho Sản xuất

Kernel CUDA tùy chỉnh mang lại lợi thế hiệu suất nghiêm trọng cho các mô hình của bạn, nhưng việc xây dựng chúng cho thế giới thực có thể gây nản lòng. Làm thế nào để bạn vượt ra khỏi một hàm GPU đơn giản để tạo ra một hệ thống mạnh mẽ, có thể mở rộng mà không bị sa lầy vào thời gian xây dựng vô tận và những cơn ác mộng về sự phụ thuộc?

Chúng tôi đã tạo ra thư viện kernel-builder cho mục đích này. Bạn có thể phát triển một kernel tùy chỉnh cục bộ, sau đó xây dựng nó cho nhiều kiến trúc và cung cấp cho thế giới sử dụng.

Trong hướng dẫn này, chúng tôi sẽ chỉ cho bạn cách xây dựng một kernel CUDA hoàn chỉnh, hiện đại từ đầu. Sau đó, chúng ta sẽ giải quyết những thách thức khó khăn về sản xuất và triển khai, dựa trên các chiến lược kỹ thuật thực tế để chỉ cho bạn cách xây dựng các hệ thống không chỉ nhanh mà còn hiệu quả và dễ bảo trì.

Bạn sẽ học được gì

Khi bạn hoàn thành, các nhà phát triển khác sẽ có thể sử dụng các kernel của bạn trực tiếp từ hub như sau:

python import torch

from kernels import get_kernel

Tải xuống kernel tùy chỉnh từ Hugging Face Hub

optimized_kernel = get_kernel(“your-username/optimized-kernel”)

Một tensor đầu vào mẫu

some_input = torch.randn((10, 10), device=“cuda”)

Chạy kernel

out = optimized_kernel.my_kernel_function(some_input)

print(out)

Thích xem video hơn? Xem video trên YouTube đi kèm với hướng dẫn này.

Hãy bắt đầu! 🚀

Phần 1: Giải phẫu của một Kernel CUDA Hiện đại

Hãy xây dựng một kernel thiết thực chuyển đổi một hình ảnh từ RGB sang thang độ xám. Ví dụ này sử dụng API C++ hiện đại của PyTorch để đăng ký hàm của chúng ta như một toán tử gốc, hạng nhất.

Bước 1: Cấu trúc dự án

Một cấu trúc sạch sẽ, có thể dự đoán được là nền tảng của một dự án tốt. Hugging Face Kernel Builder mong đợi các tệp của bạn được tổ chức như sau:

bash img2gray/ ├── build.toml ├── csrc │ └── img2gray.cu ├── flake.nix └── torch-ext ├── torch_binding.cpp ├── torch_binding.h └── img2gray └── init.py

  • build.toml: Bản kê khai dự án; nó là bộ não của quy trình xây dựng.
  • csrc/: Mã nguồn CUDA thô của bạn, nơi điều kỳ diệu của GPU diễn ra.
  • flake.nix: Chìa khóa để có một môi trường xây dựng có thể tái tạo hoàn hảo*.
  • torch-ext/img2gray/: Trình bao bọc Python cho các toán tử PyTorch thô.

Bước 2: Bản kê khai build.toml

Tệp này điều phối toàn bộ bản dựng. Nó cho kernel-builder biết những gì cần biên dịch và cách mọi thứ kết nối.

toml

build.toml

[general] name = “img2gray” universal = false

Xác định các tệp C++ liên kết với PyTorch

[torch] src = [ “torch-ext/torch_binding.cpp”, “torch-ext/torch_binding.h” ]

Xác định kernel CUDA

[kernel.img2gray] backend = “cuda” depends = [“torch”] # Kernel này phụ thuộc vào thư viện Torch cho lớp Tensor. src = [ “csrc/img2gray.cu”, ]

Bước 3: Tệp tái tạo flake.nix

Để đảm bảo bất kỳ ai cũng có thể xây dựng kernel của bạn trên bất kỳ máy nào, chúng ta sử dụng tệp flake.nix. Nó khóa chính xác phiên bản của kernel-builder và các phụ thuộc của nó, loại bỏ các sự cố “nó hoạt động trên máy của tôi”.

nix

flake.nix

{ description = “Flake for img2gray kernel”;

inputs = { kernel-builder.url = “github:huggingface/kernel-builder”; };

outputs = { self, kernel-builder, }: kernel-builder.lib.genFlakeOutputs { path = ./.; rev = self.shortRev or self.dirtyShortRev or self.lastModifiedDate; }; }

Bước 4: Viết Kernel CUDA

Bây giờ đến mã GPU. Bên trong csrc/img2gray.cu, chúng ta sẽ xác định một kernel sử dụng lưới 2D các luồng — một sự phù hợp tự nhiên và hiệu quả để xử lý hình ảnh.

cpp // csrc/img2gray.cu #include #include <torch/torch.h>

// Kernel này chạy trên GPU, với mỗi luồng xử lý một pixel global void img2gray_kernel(const uint8_t* input, uint8_t* output, int width, int height) { int x = blockIdx.x * blockDim.x + threadIdx.x; int y = blockIdx.y * blockDim.y + threadIdx.y;

if (x < width && y < height) {
    int idx = (y * width + x) * 3; // 3 kênh cho RGB
    uint8_t r = input[idx];
    uint8_t g = input[idx + 1];
    uint8_t b = input[idx + 2];

    // Chuyển đổi độ chói
    uint8_t gray = static_cast<uint8_t>(0.21f * r + 0.72f * g + 0.07f * b);
    output[y * width + x] = gray;
}

}

// Hàm C++ này khởi chạy kernel CUDA của chúng ta void img2gray_cuda(torch::Tensor const &input, torch::Tensor &output) { const int width = input.size(1); const int height = input.size(0);

// Xác định kích thước khối và lưới 2D để xử lý ảnh
const dim3 blockSize(16, 16);
const dim3 gridSize((width + blockSize.x - 1) / blockSize.x, (height + blockSize.y - 1) / blockSize.y);

img2gray_kernel<<<gridSize, blockSize>>>(
    input.data_ptr<uint8_t>(),
    output.data_ptr<uint8_t>(),
    width,
    height
);

}

Bước 5: Đăng ký Toán tử PyTorch Gốc

Đây là bước quan trọng nhất. Chúng ta không chỉ liên kết với Python; chúng ta đang đăng ký hàm của mình như một toán tử PyTorch gốc. Điều này làm cho nó trở thành một thành viên hạng nhất trong hệ sinh thái PyTorch, hiển thị dưới không gian tên torch.ops.

Tệp torch-ext/torch_binding.cpp xử lý việc đăng ký này.

cpp // torch-ext/torch_binding.cpp #include <torch/library.h> #include “registration.h” // included in the build #include “torch_binding.h” // Khai báo hàm img2gray_cuda của chúng ta

TORCH_LIBRARY_EXPAND(TORCH_EXTENSION_NAME, ops) { ops.def(“img2gray(Tensor input, Tensor! output) -> ()”); ops.impl(“img2gray”, torch::kCUDA, &img2gray_cuda); }

REGISTER_EXTENSION(TORCH_EXTENSION_NAME)

Nói một cách đơn giản, TORCH_LIBRARY_EXPAND cho phép chúng ta xác định toán tử của mình theo cách có thể dễ dàng mở rộng hoặc sửa đổi trong tương lai.

Tại sao điều này lại quan trọng

Cách tiếp cận này rất quan trọng vì hai lý do chính:

  • Khả năng tương thích với torch.compile: Bằng cách đăng ký kernel của chúng ta theo cách này, torch.compile có thể “nhìn thấy” nó. Điều này cho phép PyTorch hợp nhất toán tử tùy chỉnh của bạn vào các đồ thị tính toán lớn hơn, giảm thiểu chi phí và tối đa hóa hiệu suất. Đây là chìa khóa để làm cho mã tùy chỉnh của bạn hoạt động liền mạch với hệ sinh thái hiệu suất rộng lớn hơn của PyTorch.
  • Triển khai dành riêng cho phần cứng: Hệ thống này cho phép bạn cung cấp các backend khác nhau cho cùng một toán tử. Bạn có thể thêm một khối TORCH_LIBRARY_IMPL(img2gray, CPU, ...) khác trỏ đến một hàm CPU C++. Bộ điều phối của PyTorch sau đó sẽ tự động gọi triển khai chính xác (CUDA hoặc CPU) dựa trên thiết bị của tensor đầu vào, làm cho mã của bạn trở nên mạnh mẽ và di động.

Thiết lập trình bao bọc __init__.py

Trong torch-ext/img2gray/, chúng ta cần một tệp __init__.py để làm cho thư mục này trở thành một gói Python và để hiển thị toán tử tùy chỉnh của chúng ta một cách thân thiện với người dùng.

Mô-đun _ops được tự động tạo bởi kernel-builder từ một mẫu để cung cấp một không gian tên tiêu chuẩn cho các hàm C++ đã đăng ký của bạn.

python

torch-ext/img2gray/init.py

import torch

from ._ops import ops

def img2gray(input: torch.Tensor) -> torch.Tensor: # chúng ta mong đợi đầu vào ở định dạng CHW height, width, channels = input.shape assert channels == 3, “Hình ảnh đầu vào phải có 3 kênh (RGB)”

output = torch.empty((height, width), device=input.device, dtype=input.dtype)
ops.img2gray(input, output)

return output

Bước 6: Xây dựng Kernel

Bây giờ kernel và các liên kết của nó đã sẵn sàng, đã đến lúc xây dựng chúng. Công cụ kernel-builder đơn giản hóa quá trình này.

Bạn có thể xây dựng kernel của mình bằng một lệnh duy nhất, nix build . -L; tuy nhiên, với tư cách là nhà phát triển, chúng ta sẽ muốn một quy trình làm việc nhanh hơn, lặp đi lặp lại hơn. Đối với điều đó, chúng ta sẽ sử dụng lệnh nix develop để vào một shell phát triển với tất cả các phụ thuộc cần thiết đã được cài đặt sẵn.

Cụ thể hơn, chúng ta có thể chọn chính xác các phiên bản CUDA và PyTorch mà chúng ta muốn sử dụng. Ví dụ: để xây dựng kernel của chúng ta cho PyTorch 2.7 với CUDA 12.6, chúng ta có thể sử dụng lệnh sau:

Vào Nix Shell

bash

Vào Nix shell (một sandbox biệt lập với tất cả các phụ thuộc)

nix develop .#devShells.torch28-cxx11-cu128-x86_64-linux

Lưu ý rằng tên devShell ở trên có thể được giải mã như sau:

nix nix develop .#devShells.torch27-cxx11-cu126-x86_64-linux │ │ │ │ │ │ │ └─── Kiến trúc: x86_64 (Linux) │ │ └────────── Phiên bản CUDA: 12.6 │ └──────────────────── ABI C++: cxx11 └──────────────────────────── Phiên bản Torch: 2.7

Tại thời điểm này, chúng ta sẽ ở bên trong Nix shell với tất cả các phụ thuộc đã được cài đặt. Bây giờ chúng ta có thể xây dựng kernel cho kiến trúc cụ thể này và kiểm tra nó. Sau này, chúng ta sẽ xử lý nhiều kiến trúc trước khi phân phối phiên bản cuối cùng của kernel.

Thiết lập Artifacts Bản dựng

bash build2cmake generate-torch build.toml

thao tác này tạo: torch-ext/img2gray/_ops.py, pyproject.toml, torch-ext/registration.h, setup.py, cmake/hipify.py, cmake/utils.cmake, CMakeLists.txt

Lệnh này tạo một số tệp được sử dụng để xây dựng kernel: CMakeLists.txt, pyproject.toml, setup.py và một thư mục cmake. Tệp CMakeLists.txt là điểm vào chính để CMake xây dựng kernel.

Tạo Môi trường Ảo Python

bash python -m venv .venv source .venv/bin/activate

Bây giờ bạn có thể cài đặt kernel ở chế độ có thể chỉnh sửa.

Biên dịch Kernel và Cài đặt Gói Python

bash pip install –no-build-isolation -e .

🙌 Tuyệt vời! Bây giờ chúng ta có một kernel được xây dựng tùy chỉnh tuân theo các phương pháp hay nhất cho các liên kết PyTorch, với một quy trình xây dựng hoàn toàn có thể tái tạo.

Chu kỳ Phát triển

Để đảm bảo mọi thứ hoạt động chính xác, chúng ta có thể chạy một thử nghiệm đơn giản để kiểm tra xem kernel đã được đăng ký và nó hoạt động như mong đợi hay không. Nếu không, bạn có thể lặp lại bằng cách chỉnh sửa các tệp nguồn và lặp lại bản dựng, sử dụng lại môi trường nix mà bạn đã tạo.

python

scripts/sanity.py

import torch import img2gray

from PIL import Image import numpy as np

print(dir(img2gray))

img = Image.open(“kernel-builder-logo-color.png”).convert(“RGB”) img = np.array(img) img_tensor = torch.from_numpy(img).cuda() print(img_tensor.shape) # HWC

gray_tensor = img2gray.img2gray(img_tensor).squeeze() print(gray_tensor.shape) # HW

lưu hình ảnh đầu ra

gray_img = Image.fromarray(gray_tensor.cpu().numpy().astype(np.uint8), mode=“L”) gray_img.save(“kernel-builder-logo-gray.png”)

Bước 7: Chia sẻ với Thế giới

Bây giờ chúng ta đã có một kernel hoạt động, đã đến lúc chia sẻ nó với các nhà phát triển khác và thế giới!

Một điều nhỏ mà chúng ta sẽ muốn làm trước khi chia sẻ là dọn dẹp tất cả các artifact phát triển đã được tạo trong quá trình xây dựng để tránh tải lên các tệp không cần thiết.

bash build2cmake clean build.toml

Xây dựng Kernel cho Tất cả các Phiên bản PyTorch và CUDA

Trước đó, chúng ta đã xây dựng kernel cho một phiên bản PyTorch và CUDA cụ thể. Tuy nhiên, để cung cấp cho một lượng khán giả rộng hơn, chúng ta cần xây dựng nó cho tất cả các phiên bản được hỗ trợ. Công cụ kernel-builder có thể giúp chúng ta việc đó.

Đây cũng là nơi khái niệm về kernel tuân thủ phát huy tác dụng. Một kernel tuân thủ là một kernel có thể được xây dựng và chạy cho tất cả các phiên bản PyTorch và CUDA được hỗ trợ. Nói chung, điều này đòi hỏi cấu hình tùy chỉnh; tuy nhiên, trong trường hợp của chúng ta, công cụ kernel-builder sẽ tự động hóa quá trình này.

bash

Bên ngoài dev shell, hãy chạy lệnh sau

nếu bạn ở bên trong sandbox, bạn có thể rời đi bằng exit

nix build . -L

Quá trình này có thể mất một thời gian, vì nó sẽ xây dựng kernel cho tất cả các phiên bản PyTorch và CUDA được hỗ trợ. Đầu ra sẽ nằm trong thư mục result.

Nhóm kernel-builder tích cực duy trì các biến thể bản dựng được hỗ trợ, giữ cho chúng luôn cập nhật với các bản phát hành PyTorch và CUDA mới nhất, đồng thời hỗ trợ các phiên bản trailing để có khả năng tương thích rộng hơn.

Bước cuối cùng là di chuyển kết quả vào thư mục build dự kiến (đây là nơi thư viện kernels sẽ tìm kiếm chúng).

bash mkdir -p build rsync -av –delete –chmod=Du+w,Fu+w result/ build/

Đẩy lên Hugging Face Hub

Đẩy artifact xây dựng lên Hub sẽ giúp các nhà phát triển khác sử dụng kernel của bạn một cách đơn giản, như chúng ta đã thấy trong bài đăng trước của chúng ta.

Đầu tiên, tạo một repo mới:

bash hf repo create img2gray

Đảm bảo bạn đã đăng nhập vào Hugging Face Hub bằng huggingface-cli login.

Bây giờ, trong thư mục dự án của bạn, hãy kết nối dự án của bạn với kho lưu trữ mới và đẩy mã của bạn:

bash

Khởi tạo git và kết nối với Hugging Face Hub

git init git remote add origin https://huggingface.co//img2gray

Kéo các thay đổi (chỉ tệp .gitattributes mặc định)

git pull origin main git lfs install git checkout -b main

Cập nhật để sử dụng LFS cho các tệp nhị phân

git lfs track “*.so”

Thêm và cam kết các thay đổi của bạn. (cẩn thận chỉ bao gồm các tệp cần thiết

vì lệnh build2cmake của chúng ta đã tạo ra rất nhiều tệp dành riêng cho dev)

git add
build/ csrc/
torch-ext/torch_binding.cpp torch-ext/torch_binding.h torch-ext/img2gray
flake.nix flake.lock build.toml

git commit -m “feat: Đã tạo kernel img2gray tuân thủ” git push -u origin main

Tuyệt vời! Kernel của bạn hiện đang ở trên Hugging Face Hub, sẵn sàng cho những người khác sử dụng và hoàn toàn tương thích với thư viện kernels. Kernel của chúng ta và tất cả các biến thể xây dựng của nó hiện có tại drbh/img2gray.

Bước 8: Tải và Kiểm tra Toán tử Tùy chỉnh của Bạn

Với thư viện kernels, bạn không “cài đặt” kernel theo nghĩa truyền thống. Bạn tải nó trực tiếp từ kho lưu trữ Hub của nó, kho này sẽ tự động đăng ký toán tử mới.

python

/// script

requires-python = “==3.10”

dependencies = [

“kernels”,

“numpy”,

“pillow”,

“torch”,

]

///

import torch from PIL import Image import numpy as np from kernels import get_kernel

Thao tác này tải xuống, lưu vào bộ nhớ cache và tải thư viện kernel

và làm cho op tùy chỉnh có sẵn trong torch.ops

img2gray_lib = get_kernel(“drbh/img2gray”)

img = Image.open(“kernel-builder-logo-color.png”).convert(“RGB”) img = np.array(img) img_tensor = torch.from_numpy(img).cuda() print(img_tensor.shape) # HWC

gray_tensor = img2gray_lib.img2gray(img_tensor).squeeze() print(gray_tensor.shape) # HW

lưu hình ảnh đầu ra

gray_img = Image.fromarray(gray_tensor.cpu().numpy().astype(np.uint8), mode=“L”) gray_img.save(“kernel-builder-logo-gray2.png”)


Phần 2: Từ một Kernel đến Nhiều: Giải quyết các Thách thức Sản xuất

Khi bạn đã có một kernel sẵn sàng sử dụng, có một số điều bạn có thể làm để giúp bạn triển khai kernel dễ dàng hơn. Chúng ta sẽ thảo luận về việc sử dụng kiểm soát phiên bản như một công cụ để thực hiện các thay đổi API mà không làm phá vỡ việc sử dụng kernel ở hạ nguồn. Sau đó, chúng ta sẽ kết thúc bằng cách chỉ ra cách bạn có thể tạo bánh xe Python cho kernel của mình.

Phiên bản Kernel

Bạn có thể quyết định cập nhật kernel của mình sau một thời gian. Có thể bạn đã tìm thấy những cách mới để cải thiện hiệu suất hoặc có thể bạn muốn mở rộng chức năng của kernel. Một số thay đổi sẽ yêu cầu bạn thay đổi API của kernel của mình. Ví dụ: một phiên bản mới hơn có thể thêm một đối số bắt buộc mới vào một trong các hàm công khai. Điều này có thể gây bất tiện cho người dùng ở hạ nguồn, vì mã của họ sẽ bị hỏng cho đến khi họ thêm đối số mới này.

Người dùng ở hạ nguồn của kernel có thể tránh sự cố này bằng cách ghim kernel mà họ sử dụng vào một bản sửa đổi cụ thể. Ví dụ: vì mỗi kho lưu trữ Hub cũng là một kho lưu trữ Git, nên họ có thể sử dụng git commit shorthash để ghim kernel vào một bản sửa đổi:

python from kernels import get_kernel img2gray_lib = get_kernel(“drbh/img2gray”, revision=“4148918”)

Sử dụng Git shorthash sẽ làm giảm khả năng xảy ra sự cố; tuy nhiên, nó rất khó giải thích và không cho phép nâng cấp duyên dáng trong một phạm vi phiên bản. Do đó, chúng tôi khuyên bạn nên sử dụng hệ thống kiểm soát phiên bản ngữ nghĩa quen thuộc cho các kernel Hub. Việc thêm một phiên bản vào kernel rất dễ dàng: bạn chỉ cần thêm một thẻ Git có dạng vx.y.z trong đó x.y.z là phiên bản. Ví dụ: nếu phiên bản hiện tại của kernel là 1.1.2, bạn có thể gắn thẻ nó là v1.1.2. Sau đó, bạn có thể lấy phiên bản đó bằng get_kernel:

python from kernels import get_kernel img2gray_lib = get_kernel(“drbh/img2gray”, revision=“v1.1.2”)

Kiểm soát phiên bản thậm chí còn mạnh mẽ hơn với các ràng buộc phiên bản. Trong kiểm soát phiên bản ngữ nghĩa, phiên bản 1.y.z không được có các thay đổi không tương thích ngược trong API công khai cho mỗi xy kế tiếp. Vì vậy, nếu phiên bản của kernel là 1.1.2 vào thời điểm viết mã của bạn, bạn có thể yêu cầu phiên bản phải ít nhất là 1.1.2, nhưng nhỏ hơn 2.0.0:

python from kernels import get_kernel img2gray_lib = get_kernel(“drbh/img2gray”, version=">=1.1.2,<2")

Điều này sẽ đảm bảo rằng mã sẽ luôn tìm nạp kernel mới nhất từ ​​sê-ri 1.y.z. Ràng buộc phiên bản có thể là kiểu Python chỉ định phiên bản.

Bạn có thể gắn thẻ một phiên bản bằng huggingface-cli:

bash $ huggingface-cli tag drbh/img2gray v1.1.2

Khóa Kernel

Trong các dự án lớn, bạn có thể muốn điều phối các phiên bản kernel trên toàn cầu thay vì trong mỗi lệnh gọi get_kernel. Hơn nữa, thường hữu ích khi khóa kernel, để tất cả người dùng của bạn có cùng phiên bản kernel, điều này giúp xử lý các báo cáo lỗi.

Thư viện kernels cung cấp một cách hay để quản lý kernel ở cấp dự án. Để thực hiện việc này, hãy thêm gói kernels vào các yêu cầu của hệ thống xây dựng của dự án bạn, trong tệp pyproject.toml. Sau khi thực hiện việc này, bạn có thể chỉ định các yêu cầu kernel của dự án bạn trong phần tools.kernels:

toml [build-system] requires = [“kernels”, “setuptools”] build-backend = “setuptools.build_meta”

[tool.kernels.dependencies] “drbh/img2gray” = “>=0.1.2,<0.2.0”

Phiên bản có thể được chỉ định với cùng loại chỉ định phiên bản như các phụ thuộc Python. Đây là một nơi khác mà các thẻ phiên bản (va.b.c) trở nên hữu ích - kernels sẽ sử dụng các thẻ phiên bản của kho lưu trữ để truy vấn những phiên bản nào có sẵn. Sau khi chỉ định một kernel trong pyproject.toml, bạn có thể khóa nó vào một phiên bản cụ thể bằng tiện ích dòng lệnh kernels. Tiện ích này là một phần của gói Python kernels:

bash $ kernels lock .

Thao tác này tạo ra một tệp kernels.lock với các phiên bản kernel mới nhất tương thích với các ràng buộc được chỉ định trong pyproject.toml. kernels.lock phải được cam kết vào kho lưu trữ Git của dự án của bạn, để mọi người dùng của dự án sẽ nhận được các phiên bản kernel đã khóa. Khi các phiên bản kernel mới hơn được phát hành, bạn có thể chạy lại kernels lock để cập nhật tệp khóa.

Bạn cần một bit cuối cùng để triển khai đầy đủ các kernel đã khóa trong một dự án. get_locked_kernel là đối tác với get_kernel sử dụng các kernel đã khóa. Vì vậy, để sử dụng các kernel đã khóa, hãy thay thế mọi lần xuất hiện của get_kernel bằng get_locked_kernel:

python from kernels import get_kernel img2gray_lib = get_locked_kernel(“drbh/img2gray”)

Thế thôi! Mọi lệnh gọi get_locked_kernel("drbh/img2gray") trong dự án bây giờ sẽ sử dụng phiên bản được chỉ định trong kernels.lock.

Tải trước các Kernel Đã khóa

Hàm get_locked_kernel sẽ tải xuống kernel khi nó không có sẵn trong bộ nhớ cache Hub cục bộ. Điều này không lý tưởng cho các ứng dụng mà bạn không muốn tải xuống các tệp nhị phân tại thời gian chạy. Ví dụ: khi bạn đang xây dựng một hình ảnh Docker cho một ứng dụng, bạn thường muốn các kernel được lưu trữ trong hình ảnh cùng với ứng dụng. Điều này có thể được thực hiện trong hai bước đơn giản.

Đầu tiên, sử dụng hàm load_kernel thay cho get_locked_kernel:

python from kernels import get_kernel img2gray_lib = load_kernel(“drbh/img2gray”)

Như tên cho thấy, hàm này sẽ chỉ tải một kernel, nó sẽ không bao giờ cố gắng tải xuống kernel từ Hub. load_kernel sẽ đưa ra một ngoại lệ nếu kernel không có sẵn cục bộ. Vậy, làm cách nào để bạn làm cho các kernel có sẵn cục bộ? Tiện ích kernels đã giúp bạn! Chạy kernels download . sẽ tải xuống các kernel được chỉ định trong kernels.lock. Vì vậy, ví dụ: trong một vùng chứa Docker, bạn có thể thêm một bước:

dockerfile RUN kernels download /path/to/your/project

và các kernel sẽ được đưa vào hình ảnh Docker của bạn.

Kernel sử dụng bộ nhớ cache Hugging Face tiêu chuẩn, vì vậy tất cả các quy tắc bộ nhớ cache HF_HOME đều được áp dụng.

Tạo Bánh xe Python Kế thừa

Chúng tôi đặc biệt khuyên bạn nên tải xuống kernel từ Hub bằng gói kernels. Điều này có nhiều lợi ích:

  • kernels hỗ trợ tải nhiều phiên bản kernel của cùng một kernel trong một quy trình Python.
  • kernels sẽ tự động tải một phiên bản của kernel tương thích với các phiên bản CUDA và Torch của môi trường của bạn.
  • Bạn sẽ nhận được tất cả những lợi ích của Hub: phân tích, theo dõi sự cố, yêu cầu kéo, các nhánh, v.v.
  • Hub và kernel-builder cung cấp nguồn gốc và khả năng tái tạo, người dùng có thể xem lịch sử nguồn của kernel và xây dựng lại nó trong cùng một môi trường xây dựng để xác minh.

Điều đó có nghĩa là, một số dự án có thể yêu cầu triển khai kernel dưới dạng bánh xe. Tiện ích kernels cung cấp một giải pháp đơn giản cho việc này. Bạn có thể chuyển đổi bất kỳ kernel Hub nào thành một tập hợp các bánh xe bằng một lệnh duy nhất:

bash $ kernels to-wheel drbh/img2grey 1.1.2 ☸ img2grey-1.1.2+torch27cu128cxx11-cp39-abi3-manylinux_2_28_x86_64.whl ☸ img2grey-1.1.2+torch26cu124cxx11-cp39-abi3-manylinux_2_28_x86_64.whl ☸ img2grey-1.1.2+torch26cu126cxx11-cp39-abi3-manylinux_2_28_x86_64.whl ☸ img2grey-1.1.2+torch27cu126cxx11-cp39-abi3-manylinux_2_28_x86_64.whl ☸ img2grey-1.1.2+torch26cu126cxx98-cp39-abi3-manylinux_2_28_x86_64.whl ☸ img2grey-1.1.2+torch27cu128cxx11-cp39-abi3-manylinux_2_28_aarch64.whl ☸ img2grey-1.1.2+torch26cu126cxx98-cp39-abi3-manylinux_2_28_aarch64.whl ☸ img2grey-1.1.2+torch27cu126cxx11-cp39-abi3-manylinux_2_28_aarch64.whl ☸ img2grey-1.1.2+torch26cu126cxx11-cp39-abi3-manylinux_2_28_aarch64.whl ☸ img2grey-1.1.2+torch26cu118cxx98-cp39-abi3-manylinux_2_28_x86_64.whl ☸ img2grey-1.1.2+torch26cu124cxx98-cp39-abi3-manylinux_2_28_x86_64.whl ☸ img2grey-1.1.2+torch26cu118cxx11-cp39-abi3-manylinux_2_28_x86_64.whl ☸ img2grey-1.1.2+torch27cu118cxx11-cp39-abi3-manylinux_2_28_x86_64.whl

Mỗi một trong số các bánh xe này sẽ hoạt động như bất kỳ bánh xe Python nào khác: kernel có thể được nhập bằng một import img2grey đơn giản.

Kết luận

Hướng dẫn này đã hướng dẫn bạn toàn bộ vòng đời của một kernel CUDA sẵn sàng cho sản xuất. Bạn đã thấy cách xây dựng một kernel tùy chỉnh từ đầu, đăng ký nó như một toán tử PyTorch gốc và chia sẻ nó với cộng đồng trên Hugging Face Hub. Chúng tôi cũng đã khám phá các phương pháp hay nhất để kiểm soát phiên bản, quản lý sự phụ thuộc và triển khai, đảm bảo công việc của bạn vừa mạnh mẽ vừa dễ bảo trì.

Chúng tôi tin rằng phát triển mở và hợp tác là chìa khóa để đổi mới. Bây giờ bạn đã có các công cụ và kiến ​​thức để xây dựng các kernel hiệu suất cao của riêng mình, chúng tôi rất vui khi thấy những gì bạn tạo ra! Chúng tôi nhiệt liệt mời bạn chia sẻ công việc của bạn, đặt câu hỏi và bắt đầu thảo luận trên Kernel Hub hoặc trong kho lưu trữ GitHub kernel-builderkho lưu trữ GitHub kernel của chúng tôi. Cho dù bạn là một nhà phát triển dày dặn kinh nghiệm hay chỉ mới bắt đầu, cộng đồng luôn ở đây để hỗ trợ bạn.

Hãy bắt đầu xây dựng! 🚀

Recommended for You

Chào mừng EmbeddingGemma, mô hình nhúng hiệu quả mới của Google

Chào mừng EmbeddingGemma, mô hình nhúng hiệu quả mới của Google

Các thủ thuật từ OpenAI gpt-oss mà BẠN 🫵 có thể sử dụng với transformers

Các thủ thuật từ OpenAI gpt-oss mà BẠN 🫵 có thể sử dụng với transformers