Mô hình và nền tảng AI

Khung Nguồn BitNet.cpp Của Microsoft Đưa Mô Hình Ngôn Ngữ Lớn 1-Bit Đến Thiết Bị Địa Phương

mm
Thêm Unite.AI vào các nguồn ưu tiên của bạn trên Google

Vào ngày 17 tháng 10 năm 2024, Microsoft đã công bố BitNet.cpp (MSFT ), một khung nguồn dùng để chạy mô hình ngôn ngữ lớn (LLM) 1-bit lượng tử hóa. BitNet.cpp là một bước tiến quan trọng trong lĩnh vực trí tuệ nhân tạo, cho phép triển khai mô hình ngôn ngữ lớn 1-bit một cách hiệu quả trên CPU tiêu chuẩn, mà không cần đến GPU đắt tiền. Sự phát triển này giúp mở rộng khả năng tiếp cận mô hình ngôn ngữ lớn, giúp chúng trở nên có sẵn trên nhiều thiết bị và mang lại những khả năng mới cho các ứng dụng trí tuệ nhân tạo trên thiết bị.

Hiểu Về Mô Hình Ngôn Ngữ Lớn 1-Bit

Mô hình ngôn ngữ lớn (LLM) truyền thống đòi hỏi tài nguyên tính toán đáng kể do sử dụng số dấu phẩy động chính xác cao (thường là FP16 hoặc BF16) cho trọng số mô hình. Điều này đã khiến việc triển khai mô hình ngôn ngữ lớn trở nên tốn kém và tiêu tốn năng lượng.

Ở cốt lõi, mô hình ngôn ngữ lớn 1-bit sử dụng các kỹ thuật lượng tử hóa cực đoan để biểu diễn trọng số mô hình bằng chỉ ba giá trị có thể: -1, 0 và 1, do đó thuật ngữ “1,58 bit” (vì nó đòi hỏi hơi hơn một bit để mã hóa ba trạng thái).

Hệ Thống Trọng Số Ternary

Khái Niệm

Lượng tử hóa 1-bit trong BitNet.cpp là một hệ thống trọng số ternary. BitNet hoạt động với chỉ ba giá trị có thể cho mỗi tham số:

  • -1 (tiêu cực)
  • 0 (trung lập)
  • 1 (tích cực)

Điều này dẫn đến yêu cầu lưu trữ khoảng 1,58 bit cho mỗi tham số, do đó tên BitNet b1.58. Sự giảm đáng kể này trong chiều rộng bit của tham số dẫn đến giảm đáng kể về sử dụng bộ nhớ và độ phức tạp tính toán, vì hầu hết các phép nhân dấu phẩy động được thay thế bằng các phép cộng và trừ đơn giản.

Cơ Sở Toán Học

Lượng tử hóa 1-bit liên quan đến việc chuyển đổi trọng số và hoạt hóa thành biểu diễn ternary của chúng thông qua các bước sau:

1. Lượng Tử Hóa Trọng Số

Lượng tử hóa trọng số liên quan đến việc tập trung chúng xung quanh giá trị trung bình (α), dẫn đến biểu diễn ternary. Biến đổi được biểu thị toán học như sau:

Wf​=Sign(W−α)

Trong đó:

  • W là ma trận trọng số ban đầu.
  • α là giá trị trung bình của trọng số.
  • Sign(x) trả về +1 nếu x > 0 và -1 nếu không.

2. Lượng Tử Hóa Hoạt Hóa

Lượng tử hóa hoạt hóa đảm bảo rằng đầu vào bị giới hạn trong một độ rộng bit nhất định:

x^e​=Quant(x)=Clip(γx×Qb​​,−Qb​+ϵ,Qb​−ϵ)

Trong đó:

  • Qb = 2(b−1)2^{(b-1)} là mức lượng tử hóa tối đa cho độ rộng bit b.
  • γ là giá trị tuyệt đối tối đa của x (kể đến như ∣∣x∣∣∞).
  • ε là một số nhỏ để ngăn chặn tràn trong quá trình tính toán.

3. Hoạt Động BitLinear

Lớp BitLinear thay thế các phép nhân ma trận truyền thống bằng một hoạt động được đơn giản hóa:

y=Wf​×x^e​×(Qb​βγ​)

Trong đó:

  • β là một yếu tố tỷ lệ được sử dụng để giảm thiểu lỗi xấp xỉ.
  • γ tỷ lệ hoạt hóa.
  • Q_b là yếu tố lượng tử hóa.

Biến đổi này cho phép tính toán hiệu quả trong khi vẫn giữ được hiệu suất của mô hình.

Ảnh Hưởng Hiệu Suất

Hiệu Suất Bộ Nhớ

Hệ thống trọng số ternary giảm đáng kể yêu cầu về bộ nhớ:

  • Mô Hình Ngôn Ngữ Lớn Truyền Thống: 16 bit cho mỗi trọng số
  • BitNet.cpp: 1,58 bit cho mỗi trọng số

Sự giảm này tương đương với tiết kiệm bộ nhớ khoảng 90% so với mô hình 16 bit truyền thống, cho phép các mô hình lớn hơn phù hợp trong cùng một giới hạn phần cứng.

Hiệu Suất Năng Lượng

Tốc Độ suy luận, Hiệu Suất Năng Lượng (Apple M2)

 

Tốc Độ Suy Luận: Nhanh Hơn Trên Cả Hai CPU

Tốc Độ Suy Luận, Hiệu Suất Năng Lượng (i7-13700H)

1. Tốc Độ Suy Luận: Nhanh Hơn Trên Cả Hai CPU

Tốc độ suy luận được biểu diễn bằng số lượng token được xử lý mỗi giây. Dưới đây là phân tích về các quan sát:

  • Trên Apple M2 Ultra: BitNet.cpp đạt tốc độ tăng lên đến 5,07 lần cho các mô hình lớn hơn (30B) so với Llama.cpp, với tốc độ đỉnh là 593,43 token mỗi giây cho mô hình 125M, điều này là 1,37 lần tốc độ. Đối với các mô hình lớn hơn như 3,8B và 7B, BitNet.cpp duy trì tốc độ trên 84,77 token mỗi giây, cho thấy hiệu quả của nó trên nhiều quy mô.
  • Trên Intel i7-13700H: BitNet.cpp đạt được những cải tiến về tốc độ thậm chí còn ấn tượng hơn. Ở kích thước mô hình 7B, BitNet.cpp cung cấp tốc độ tăng 5,68 lần so với Llama.cpp. Đối với mô hình nhỏ hơn như 125M, nó xử lý 389,08 token mỗi giây, điều này là 2,37 lần nhanh hơn Llama.cpp.

2. Hiệu Suất Năng Lượng: Một Trò Chơi Đổi Mới Cho Thiết Bị Cạnh

Các biểu đồ cũng bao gồm so sánh chi phí năng lượng, cho thấy sự giảm đáng kể trong tiêu thụ năng lượng trên mỗi token được xử lý:

  • Trên Apple M2 Ultra: Tiết kiệm năng lượng của BitNet.cpp là đáng kể. Đối với mô hình 700M, nó tiêu thụ 55,4% ít năng lượng hơn trên mỗi token so với Llama.cpp, giảm từ 0,314 xuống 0,140. Xu hướng này tiếp tục với các mô hình lớn hơn, với mô hình 70B cho thấy giảm 70,0% tiêu thụ năng lượng.
  • Trên Intel i7-13700H: BitNet.cpp mang lại tiết kiệm năng lượng 71,9% cho mô hình 700M, với tiêu thụ giảm từ 1,367 xuống 0,384. Mặc dù dữ liệu năng lượng cho mô hình 70B trong Llama.cpp không có sẵn, BitNet.cpp vẫn hiệu quả, với tiêu thụ năng lượng là 17,33 cho mô hình 70B.

3. Vượt Qua Ngưỡng Tốc Độ Đọc Của Con Người

Một trong những thông tin thú vị nhất từ các biểu đồ là tham chiếu đến tốc độ đọc của con người, được đánh dấu ở 5-7 token mỗi giây. Dòng màu đỏ này cho thấy cả hai triển khai, đặc biệt là BitNet.cpp, có thể dễ dàng vượt qua tốc độ đọc của con người ngay cả đối với các mô hình lớn nhất:

  • Trên Apple M2 Ultra, BitNet.cpp vượt qua tốc độ đọc của con người cho tất cả các kích thước mô hình, với tốc độ thấp nhất là 8,67 token mỗi giây cho mô hình 70B.
  • Trên Intel i7-13700H, mô hình 100B vẫn đạt được 1,70 token mỗi giây, gần đạt đến phạm vi dưới của tốc độ đọc của con người, trong khi tất cả các mô hình nhỏ hơn đều vượt qua ngưỡng này.

Cân Nhắc Khi Huấn Luyện

Định Giá Straight-Through (STE)

Vì lượng tử hóa 1-bit giới thiệu các hàm không khả vi, quá trình huấn luyện liên quan đến một kỹ thuật chuyên dụng được gọi là Định Giá Straight-Through (STE). Trong phương pháp này, các gradient chảy không thay đổi qua các điểm không khả vi. Dưới đây là một triển khai đơn giản trong Python:

class StraightThroughEstimator(Function):
@staticmethod
def forward(ctx, input):
return input.sign()

@staticmethod
def backward(ctx, grad_output):
return grad_output

Huấn Luyện Chính Xác Kết Hợp

Để duy trì sự ổn định trong quá trình huấn luyện, chính xác kết hợp được sử dụng:

  • Trọng Số và Hoạt Hóa: Lượng tử hóa đến độ chính xác 1-bit.
  • Độ Dốc và Trạng Thái Tối Ưu: Lưu trữ ở độ chính xác cao hơn.
  • Trọng Số Ẩn: Duy trì ở độ chính xác cao để cho phép cập nhật chính xác trong quá trình huấn luyện.

Chiến Lược Tốc Độ Học Lớn

Một thách thức duy nhất với mô hình 1-bit là các cập nhật nhỏ có thể không ảnh hưởng đến trọng số đã lượng tử hóa. Để giảm thiểu điều này, tốc độ học được tăng lên, đảm bảo sự hội tụ nhanh hơn và tối ưu hóa tốt hơn so với các phương pháp truyền thống.

Lượng Tử Hóa Nhóm và Chuẩn Hóa

BitNet.cpp giới thiệu Lượng Tử Hóa Nhóm và Chuẩn Hóa để tăng cường song song hóa mô hình. Thay vì tính toán tham số cho toàn bộ ma trận trọng số, BitNet chia trọng số và hoạt hóa thành nhiều nhóm (G).
Điều này cho phép xử lý song song hiệu quả mà không cần giao tiếp giữa các nhóm, cho phép huấn luyện và suy luận mô hình quy mô lớn.

Lưu Ý Về Triển Khai và Tối Ưu Hóa

Tối Ưu Hóa CPU

BitNet.cpp tận dụng một số tối ưu hóa cấp thấp để đạt được hiệu suất CPU tối ưu:

  • Hoạt Động Vector: Sử dụng các lệnh SIMD để thực hiện các thao tác bit một cách hiệu quả.
  • Truy Cập Bộ Nhớ Hữu Dụng: Cấu trúc dữ liệu để giảm thiểu việc bỏ lỡ bộ nhớ đệm.
  • Xử Lý Song Song: Phân phối tải công việc hiệu quả trên nhiều lõi CPU.

Dưới đây là một ví dụ về một hàm quan trọng triển khai lượng tử hóa và suy luận trong BitNet:


def bitlinear_forward(input, weight, scale):
# Lượng tử hóa đầu vào bằng cách sử dụng lượng tử hóa absmax
input_q = quantize(input)

# Thực hiện nhân ma trận nhị phân
output = binary_matmul(input_q, weight)

# Tỷ lệ đầu ra để khớp với độ chính xác ban đầu
return output * scale

def quantize(x):
# Thực hiện lượng tử hóa absmax
scale = torch.max(torch.abs(x))
return torch.clamp(x / scale, -1, 1) * scale
[/code]

Mô Hình Hỗ Trợ

Phiên bản hiện tại của BitNet.cpp hỗ trợ các mô hình ngôn ngữ lớn 1-bit sau trên Hugging Face:

  • bitnet_b1_58-large (0,7 tỷ tham số)
  • bitnet_b1_58-3B (3,3 tỷ tham số)
  • Llama3-8B-1.58-100B-tokens (8,0 tỷ tham số)

Những mô hình này có sẵn công khai để chứng minh khả năng suy luận của khung. Mặc dù không được huấn luyện hoặc phát hành chính thức bởi Microsoft, chúng minh họa sự linh hoạt của khung.

Hướng Dẫn Cài Đặt

Để bắt đầu với BitNet.cpp, hãy làm theo các bước sau:

Điều Kiện Tiên Quyết

  1. Python >= 3.9
  2. CMake >= 3.22
  3. Clang >= 18
  4. Conda (khuyến nghị cao)

Đối với người dùng Windows, Visual Studio nên được cài đặt với các thành phần sau được kích hoạt:

  • Phát triển máy tính để bàn với C++
  • Công cụ C++-CMake cho Windows
  • Git cho Windows
  • Trình biên dịch C++-Clang cho Windows
  • Hỗ trợ MS-Build cho Bộ Công Cụ LLVM (Clang)

Đối với người dùng Debian/Ubuntu, một kịch bản cài đặt tự động có sẵn:

bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"

Cài Đặt Bước Bước

  1. Clone Kho Lưu Trữ:
    git clone --recursive https://github.com/microsoft/BitNet.git

    cd BitNet
  2. Cài Đặt Phụ Thuộc:
    # Tạo một môi trường Conda mới (khuyến nghị)
    conda create -n bitnet-cpp python=3.9
    conda activate bitnet-cpp


    pip install -r requirements.txt
  3. Xây Dựng và Chuẩn Bị Dự Án: Bạn có thể tải mô hình trực tiếp từ Hugging Face và chuyển đổi nó sang định dạng lượng tử hóa:
    python setup_env.py --hf-repo HF1BitLLM/Llama3-8B-1.58-100B-tokens -q i2_s

    Hoặc, tải và chuyển đổi mô hình thủ công:

    huggingface-cli download HF1BitLLM/Llama3-8B-1.58-100B-tokens --local-dir models/Llama3-8B-1.58-100B-tokens

    python setup_env.py -md models/Llama3-8B-1.58-100B-tokens -q i2_s

Chạy Suy Luận Với BitNet.cpp

Để chạy suy luận bằng khung, sử dụng lệnh sau:

python run_inference.py -m models/Llama3-8B-1.58-100B-tokens/ggml-model-i2_s.gguf -p "Sandra đi đến nhà bếp. Ở đâu Sandra?" -n 6 -temp 0.7

Giải Thích:

  • -m chỉ định đường dẫn tệp mô hình.
  • -p định nghĩa văn bản kích hoạt.
  • -n đặt số lượng token để dự đoán.
  • -temp điều chỉnh sự ngẫu nhiên của mẫu (nhiệt độ) trong quá trình suy luận.

Ví Dụ Đầu Ra

Sandra đi đến nhà bếp. Ở đâu Sandra?

Đáp Án: Sandra ở trong nhà bếp.

Chi Tiết Kỹ Thuật Của BitNet.cpp

Lớp BitLinear

BitNet.cpp triển khai một kiến trúc Transformer được sửa đổi, thay thế các phép nhân ma trận tiêu chuẩn bằng các hoạt động BitLinear. Cách tiếp cận này tập trung trọng số vào zero trước khi lượng tử hóa và tỷ lệ chúng để giảm thiểu lỗi xấp xỉ. Hàm biến đổi chính trông như sau:

# Hàm lượng tử hóa trọng số 1-bit
def binarize_weights(W):
alpha = W.mean()
W_binarized = np.sign(W - alpha)
return W_binarized

Sự kết hợp giữa trọng số tập trung và tỷ lệ đảm bảo rằng lỗi lượng tử hóa vẫn tối thiểu, do đó giữ nguyên hiệu suất.

Ảnh Hưởng Ngành

BitNet.cpp có thể có những tác động sâu rộng đến việc triển khai mô hình ngôn ngữ lớn:

  • Tính Khả Dụng: Cho phép mô hình ngôn ngữ lớn chạy trên thiết bị tiêu chuẩn, dân chủ hóa khả năng tiếp cận trí tuệ nhân tạo mạnh mẽ.
  • Hiệu Quả Chi Phí: Giảm nhu cầu về GPU đắt tiền, giảm rào cản cho việc áp dụng.
  • Hiệu Suất Năng Lượng: Tiết kiệm năng lượng bằng cách tận dụng khả năng suy luận trên CPU.
  • Sáng Tạo: Mở ra những khả năng mới cho ứng dụng trí tuệ nhân tạo trên thiết bị, như dịch ngôn ngữ thời gian thực, trợ lý giọng nói và ứng dụng tập trung vào quyền riêng tư mà không cần phụ thuộc vào đám mây.

Thử Thách và Hướng Tiếp Cận Tương Lai

Mặc dù mô hình ngôn ngữ lớn 1-bit đầy hứa hẹn, vẫn còn một số thách thức. Những thách thức này bao gồm việc phát triển các mô hình 1-bit mạnh mẽ cho nhiều nhiệm vụ, tối ưu hóa phần cứng cho tính toán 1-bit và khuyến khích các nhà phát triển áp dụng mô hình mới này. Ngoài ra, việc khám phá lượng tử hóa 1-bit cho các nhiệm vụ thị giác máy tính hoặc âm thanh cũng đại diện cho một hướng đi thú vị trong tương lai.

Kết Luận

Việc ra mắt BitNet.cpp của Microsoft là một bước tiến quan trọng. Bằng cách cho phép suy luận 1-bit hiệu quả trên CPU tiêu chuẩn, BitNet.cpp tạo ra sự khả dụng và tính bền vững của trí tuệ nhân tạo. Khung này đặt nền tảng cho các mô hình ngôn ngữ lớn di động và tiết kiệm chi phí hơn, mở rộng những gì có thể với trí tuệ nhân tạo trên thiết bị.

Tôi đã dành 5 năm qua để đắm mình trong thế giới hấp dẫn của Máy học và Học sâu. Đam mê và chuyên môn của tôi đã dẫn tôi đến việc đóng góp vào hơn 50 dự án kỹ thuật phần mềm đa dạng, với sự tập trung đặc biệt vào AI/ML. Sự tò mò liên tục của tôi cũng đã thu hút tôi đến với Xử lý Ngôn ngữ Tự nhiên, một lĩnh vực tôi渴望 khám phá thêm.