27 February, 2025

Các định dạng model AI phổ biến

Khám phá các định dạng khác nhau, bao gồm GGUF, Safetensors, PyTorch, và ONNX

Các định dạng model AI phổ biến
Available in:
 English
 Vietnamese
Reading time: 13 min.
Table of content

    Trong hai năm qua, cộng đồng AI mã nguồn mở đã bùng nổ khi các model mới liên tục ra đời. Cứ mỗi ngày, ta lại có càng có nhiều model được upload lên Hugging Face, và rất nhiều model này đã được ứng dụng trong các dự án thực tế (production). Tuy nhiên, một thách thức mà các lập trình viên gặp phải chính là sự đa dạng về định dạng của các model.

    Bài viết này sẽ cùng bạn khám phá một số định dạng model AI phổ biến hiện nay, bao gồm GGUF, PyTorch, Safetensors và ONNX. Chúng ta sẽ cùng phân tích ưu, nhược điểm của từng định dạng và đưa ra hướng dẫn về cách lựa chọn sử dụng chúng.

    GGUF

    GGUF ban đầu được phát triển cho dự án llama.cpp. Đây là một định dạng binary được thiết kế nhằm tăng tốc quá trình tải và lưu model, đồng thời đảm bảo khả năng đọc file dễ dàng. Thông thường, các model được phát triển bằng PyTorch hoặc một framework khác, sau đó sẽ được chuyển đổi sang GGUF để sử dụng với GGML.

    Theo thời gian, GGUF đã trở thành một trong những định dạng phổ biến nhất để chia sẻ model AI trong cộng đồng mã nguồn mở. Nó được hỗ trợ bởi nhiều runtime inference nổi tiếng như llama.cpp, ollamavLLM.

    Hiện tại, GGUF chủ yếu được sử dụng cho các language model (mô hình ngôn ngữ). Mặc dù có thể áp dụng cho các loại model khác, chẳng hạn như diffusion model (tạo ảnh/video) thông qua stable-diffusion.cpp, nhưng ứng dụng này không phổ biến như đối với language model.

    Một file GGUF gồm có:

    • Model metadata: Phần này được tổ chức theo cặp key-value, chứa các thông tin như kiến trúc, phiên bản và hyperparameters của model.
    • Tensor metadata: Bao gồm các thông tin chi tiết về tensor trong model như hình dạng, kiểu dữ liệu và tên.
    • Tensor data: Phần chứa chính data của tensor.
    diagram of GGUF format structure

    Sơ đồ bởi @mishig25 (GGUF v3)

    Định dạng GGUF cùng thư viện GGML còn hỗ trợ các quantization1 schemes linh hoạt, giúp lưu trữ model một cách hiệu quả mà vẫn duy trì độ chính xác cao. Một số scheme quantization phổ biến gồm:

    • Q4_K_M: Hầu hết các tensor được quantize xuống 4 bits, trong khi một số được quantize xuống 6 bits. Đây là scheme được sử dụng phổ biến nhất.
    • IQ4_XS: Gần như tất cả các tensor đều được quantize xuống 4 bits, nhờ sự hỗ trợ của importance matrix để hiệu chỉnh quá trình quantize, từ đó có thể cải thiện độ chính xác mà vẫn tiết kiệm dung lượng.
    • IQ2_M: Tương tự như IQ4_XS nhưng với quantize 2-bit. Đây là scheme mạnh mẽ nhất, tuy nhiên vẫn đạt được độ chính xác tốt trên một số model nhất định, đặc biệt phù hợp với các thiết bị có bộ nhớ hạn chế.
    • Q8_0: Tất cả các tensor được quantize xuống 8 bits, đây là scheme ít mạnh mẽ nhất nhưng vẫn đảm bảo độ chính xác gần như với model gốc.
    Example of Llama-3.1 8B model in GGUF format

    Ví dụ về một model Llama-3.1 8B ở định dạng GGUF, xem thêm tại đây

    Tóm lại, ưu và nhược điểm của GGUF như sau:

    • Ưu điểm:
      • Đơn giản: Định dạng file đơn lẻ giúp việc chia sẻ và phân phối trở nên dễ dàng.
      • Nhanh chóng: Tốc độ tải và lưu model được cải thiện nhờ tính tương thích với mmap()2.
      • Hiệu quả: Hỗ trợ các scheme quantization linh hoạt.
      • Lưu động: Là định dạng binary, có thể đọc dễ dàng mà không cần thư viện bên thứ 3 như JSON hay protobuf.
    • Nhược điểm:
      • Hầu hết các model cần được chuyển đổi từ các định dạng khác (như PyTorch, Safetensors) sang GGUF.
      • Không phải model nào cũng có thể chuyển đổi; một số model không được hỗ trợ bởi llama.cpp.
      • Việc chỉnh sửa hay fine-tuning model sau khi đã lưu dưới định dạng GGUF không hề đơn giản.

    GGUF chủ yếu được sử dụng để triển khai model trong môi trường production, nơi mà tốc độ tải là yếu tố then chốt. Ngoài ra, định dạng này cũng được dùng một cách rất rộng rãi để chia sẻ model trong cộng đồng mã nguồn mở nhờ tính đơn giản và tiện lợi của nó.

    Tài nguyên hữu ích:

    • Dự án llama.cpp cung cấp các script chuyển đổi model từ HF sang GGUF.
    • gguf-my-repo space trên HF cho phép chuyển đổi model sang định dạng GGUF mà không cần tải về máy tính cá nhân.
    • ollama và tính năng kết nối HF-ollama hỗ trợ chạy bất kỳ model GGUF nào từ HF Hub qua lệnh ollama run.

    PyTorch (.pt/.pth)

    Phần mở rộng .pt/.pth đại diện cho định dạng serialization (biến dữ liệu thành mã nhị phân) mặc định của PyTorch, lưu trữ state dictionary chứa các tham số (weights, biases), trạng thái của optimizer và metadata liên quan đến quá trình train.

    Các model PyTorch có thể được lưu theo hai định dạng:

    • .pt: Lưu toàn bộ model, bao gồm kiến trúc và các tham số.
    • .pth: Lưu chỉ state dictionary của model, chứa các tham số và một số metadata.

    Định dạng này dựa trên module pickle của Python, dùng để serialization các đối tượng Python. Ví dụ sau minh họa cách thức hoạt động của pickle:

    import pickle
    model_state_dict = { "layer1": "hello", "layer2": "world" }
    pickle.dump(model_state_dict, open("model.pkl", "wb"))
    

    Hàm pickle.dump() serialization dictionary model_state_dict và lưu nó vào file model.pkl. File này giờ đây chứa biểu diễn binary của dictionary.

    Để tải lại dictionary đã được serialization vào Python, ta có thể sử dụng hàm pickle.load():

    import pickle
    model_state_dict = pickle.load(open("model.pkl", "rb"))
    print(model_state_dict)
    # Output: {'layer1': 'hello', 'layer2': 'world'}
    

    Module pickle cung cấp một cách đơn giản để serialization các đối tượng Python. Tuy nhiên, nó cũng tồn tại một số hạn chế:

    • Bảo mật: Bất kỳ thứ gì cũng có thể được pickle, bao gồm cả mã độc. Điều này có thể dẫn đến lỗ hổng bảo mật nếu dữ liệu đã được serialization không được kiểm tra kỹ lưỡng. Ví dụ, bài viết từ Snyk đã chỉ ra cách mà pickle files có thể bị backdoor.
    • Hiệu quả: pickle không được thiết kế cho việc lazy-loading3 hay load một phần dữ liệu, dẫn đến tốc độ load chậmtiêu thụ bộ nhớ cao khi xử lý các model lớn.
    • Tính lưu động: Vì nó chỉ dành cho Python nên chia sẻ model với các ngôn ngữ khác sẽ gặp khó khăn.

    Định dạng của PyTorch phù hợp nếu bạn chỉ làm việc trong môi trường Python và PyTorch. Tuy nhiên, trong những năm gần đây, cộng đồng AI đang chuyển sang sử dụng các định dạng serialization an toàn và hiệu quả hơn như GGUF và Safetensors.

    Tài nguyên hữu ích:

    • Tài liệu PyTorch về cách save và load model.
    • Dự án executorch cung cấp cách chuyển đổi model PyTorch sang định dạng .pte, có thể chạy trên các thiết bị di động.

    Safetensors

    Được phát triển bởi Hugging Face, safetensors giải quyết các hạn chế về bảo mật và hiệu quả của các phương pháp serialization truyền thống như pickle được sử dụng trong PyTorch. Định dạng này sử dụng một quy trình deserialization hạn chế nhằm ngăn chặn các lỗ hổng thực thi mã.

    Một file safetensors bao gồm:

    • Metadata: Được lưu dưới định dạng JSON, chứa thông tin về tất cả các tensor trong model như hình dạng, kiểu dữ liệu và tên. Phần này cũng có thể chứa metadata tuỳ chỉnh nếu cần.
    • Tensor data: Phần chứa dữ liệu của các tensor.
    Diagram of Safetensors format structure

    Sơ đồ cấu trúc định dạng Safetensors

    • Ưu điểm:
      • An toàn: Safetensors sử dụng quy trình deserialization hạn chế để ngăn chặn các lỗ hổng thực thi mã đực.
      • Nhanh: Được thiết kế cho lazy-loading và tải dữ liệu một phần, giúp giảm thời gian tải và tiết kiệm bộ nhớ - tương tự như cách sử dụng mmap()2 trong GGUF.
      • Hiệu quả: Hỗ trợ các quantize các tensor.
      • Lưu động: Định dạng này được thiết kế để có thể sử dụng trên nhiều ngôn ngữ lập trình khác nhau, giúp việc chia sẻ model dễ dàng hơn.
    • Nhược điểm:
      • Scheme quantization không linh hoạt như GGUF, chủ yếu do sự hỗ trợ từ PyTorch.
      • Việc đọc phần metadata yêu cầu có trình phân tích JSON, gây khó khăn khi làm việc với các ngôn ngữ cấp thấp như C++ vốn không tích hợp sẵn JSON.

    Lưu ý: Về lý thuyết, metadata có thể được lưu trữ trong file, nhưng trên thực tế, thường thì metadata của model được lưu riêng trong file JSON. Điều này vừa mang lại ưu điểm vừa có nhược điểm, tùy theo trường hợp sử dụng.

    Định dạng safetensors là định dạng serialization mặc định được sử dụng bởi thư viện transformers của Hugging Face. Nó được ứng dụng rộng rãi trong cộng đồng mã nguồn mở để chia sẻ, huấn luyện, fine-tuning và triển khai model AI. Các model mới trên Hugging Face đều được lưu dưới định dạng safetensors, bao gồm Llama, Gemma, Phi, Stable-Diffusion, Flux và nhiều model khác.

    Tài nguyên hữu ích:

    • Tài liệu của thư viện transformers về lưu và tải model.
    • Hướng dẫn bitsandbytes về cách quantize model và lưu dưới định dạng safetensors.
    • Nhóm mlx-community trên HF cung cấp các model tương thích với MLX framework (Apple silicon).

    ONNX

    Định dạng Open Neural Network Exchange (ONNX) cung cấp cách biểu diễn trung lập cho các model machine learning, không phụ thuộc vào nhà cung cấp. Nó là một phần của hệ sinh thái ONNX, bao gồm các công cụ và thư viện hỗ trợ khả năng tương tác giữa các framework khác nhau như PyTorch, TensorFlow hay MXNet.

    Các model ONNX được lưu trong một file đơn với phần mở rộng .onnx. Khác với GGUF hay Safetensors, ONNX không chỉ chứa các tensor và metadata của model mà còn bao gồm cả computation graph4.

    Việc tích hợp computation graph vào file model mang lại sự linh hoạt khi chuyển đổi model giữa các framework. Ví dụ, khi có một model mới được phát hành, bạn có thể dễ dàng chuyển đổi sang định dạng ONNX mà không cần phải lo lắng về kiến trúc của model hay mã inference, vì computation graph đã được lưu sẵn trong file.

    Example for a compute graph in ONNX format

    Ví dụ về computation graph trong định dạng ONNX, cung cấp bởi Netron

    • Ưu điểm:
      • Linh hoạt: Việc tích hợp computation graph trong file model giúp chuyển đổi model giữa các framework trở nên dễ dàng hơn.
      • Lưu động: Nhờ hệ sinh thái ONNX, định dạng này có thể được triển khai trên nhiều nền tảng và thiết bị, bao gồm cả thiết bị di động và edge.
    • Nhược điểm:
      • Hỗ trợ cho quantization còn hạn chế. ONNX không hỗ trợ trực tiếp quantize tensor mà tách chúng thành một integer tensor bao gồm các số nguyên và một scale factor tensor bao gồm số thập phân, điều này có thể dẫn đến giảm chất lượng khi làm việc với model đã quantize.
      • Các kiến trúc phức tạp có thể đòi hỏi phải có fallback operator hoặc triển khai tuỳ chỉnh cho những layer không được hỗ trợ, điều này có thể ảnh hưởng đến hiệu năng khi chuyển đổi model sang ONNX.

    Nhìn chung, ONNX là lựa chọn tốt nếu bạn đang làm việc với thiết bị di động hoặc thực hiện inference trực tiếp trên trình duyệt.

    Tài nguyên hữu ích:

    • Nhóm onnx-community trên HF cung cấp các model ở định dạng ONNX cũng như hướng dẫn chuyển đổi.
    • Dự án transformer.js cho phép chạy model ONNX trong trình duyệt, sử dụng WebGPU hoặc WebAssembly.
    • Dự án onnxruntime cung cấp engine inference hiệu năng cao trên nhiều nền tảng và phần cứng.
    • Dự án netron cung cấp công cụ quan sát trực quan computation graph của model ONNX.

    Hỗ Trợ Phần Cứng

    Khi chọn định dạng model, bạn cần cân nhắc phần cứng sẽ triển khai model đó. Bảng dưới đây cho thấy mức độ hỗ trợ phần cứng cho từng định dạng:

    Phần CứngGGUFPyTorchSafetensorsONNX
    CPU✅ (tốt nhất)🟡🟡
    GPU
    Triển khai trên thiết bị di động✅ (dùng executorch)
    Apple silicon🟡✅ (dùng MLX framework)

    Giải thích:

    • ✅: Hỗ trợ đầy đủ
    • 🟡: Hỗ trợ một phần hoặc hiệu năng thấp
    • ❌: Không hỗ trợ

    Kết Luận

    Trong bài viết này, chúng ta đã cùng nhau khám phá một số định dạng model AI phổ biến hiện nay, bao gồm GGUF, PyTorch, Safetensors và ONNX. Mỗi định dạng có những ưu và nhược điểm riêng, vì vậy việc lựa chọn định dạng phù hợp cần dựa trên nhu cầu sử dụng cụ thể và yêu cầu về phần cứng.

    Footnotes

    1. Quantization có thể hiểu nôm na là quá trình "nén" các tham số của model để nó chiếm ít dung lượng hơn, nhưng vẫn giữ được độ chính xác ở một mức độ chấp nhận được.

    2. Memory-mapped files là tính năng của hệ điều hành cho phép ánh xạ file vào bộ nhớ, giúp đọc và ghi các file lớn mà không cần tải toàn bộ file vào bộ nhớ. 2

    3. Lazy-loading là kỹ thuật trì hoãn việc tải data cho đến khi thật sự cần sử dụng, giúp giảm sử dụng bộ nhớ và cải thiện hiệu năng khi xử lý các model lớn.

    4. Trong machine learning, computation graph là sơ đồ thể hiện luồng dữ liệu qua model cùng cách thực hiện các phép tính (như cộng, nhân hay áp dụng activation function) ở từng bước.

    Want to receive latest articles from my blog?
    Follow on
    Discussion

      Loading comments...