Lượng tử hóa có thể được định nghĩa là quá trình ánh xạ các giá trị từ một tập hợp lớn các số thực sang các giá trị trong một tập hợp nhỏ rời rạc. Thông thường, điều này liên quan đến việc ánh xạ các đầu vào liên tục tới các giá trị cố định ở đầu ra. Một cách phổ biến để đạt được điều này là làm tròn hoặc cắt bớt. Trong trường hợp làm tròn, chúng tôi tính số nguyên gần nhất. Ví dụ: giá trị 1,8 trở thành 2. Nhưng giá trị 1,2 trở thành 1. Trong trường hợp cắt ngắn, chúng tôi loại bỏ một cách mù quáng các giá trị sau số thập phân để chuyển đổi đầu vào thành số nguyên.
Dù chúng ta tiến hành theo cách nào, động lực chính đằng sau việc lượng tử hóa mạng lưới thần kinh sâu là để cải thiện tốc độ suy luận vì không cần phải nói rằng việc suy luận và huấn luyện mạng lưới thần kinh khá tốn kém về mặt tính toán. Với sự ra đời của Mô hình ngôn ngữ lớn , số lượng tham số trong các mô hình này ngày càng tăng, đồng nghĩa với việc dung lượng bộ nhớ ngày càng cao hơn.
Với tốc độ phát triển của các mạng thần kinh này, nhu cầu chạy các mạng thần kinh này trên máy tính xách tay hoặc điện thoại di động của chúng ta và thậm chí cả các thiết bị nhỏ như đồng hồ ngày càng tăng. Không ai có thể thực hiện được điều này nếu không lượng tử hóa.
Trước khi đi sâu vào lượng tử hóa, chúng ta đừng quên rằng Mạng thần kinh đã được huấn luyện chỉ là những số trôi nổi được lưu trữ trong bộ nhớ máy tính.
Một số cách biểu diễn hoặc định dạng nổi tiếng để lưu trữ số trong máy tính là float32 hoặc FP32, float16 hoặc FP16, int8, bfloat16 trong đó B là viết tắt của Google Brain hoặc gần đây hơn là tensor float 32 hoặc TF32, một định dạng chuyên dụng để xử lý ma trận hoặc tensor hoạt động. Mỗi định dạng này tiêu thụ một đoạn bộ nhớ khác nhau. Ví dụ: float32 phân bổ 1 bit cho dấu, 8 bit cho số mũ và 23 bit cho phần định trị.
Tương tự, float16 hoặc FP16 phân bổ 1 bit cho dấu nhưng chỉ 5 bit cho số mũ và 10 bit cho phần định trị. Mặt khác, BF16 phân bổ 8 bit cho số mũ và chỉ 7 bit cho phần định trị.
Đủ các đại diện. Điều tôi muốn nói là việc chuyển đổi từ định dạng bộ nhớ cao hơn sang định dạng bộ nhớ thấp hơn được gọi là lượng tử hóa. Nói theo thuật ngữ học sâu, Float32 được gọi là độ chính xác đơn hoặc toàn bộ, còn Float16 và BFloat16 được gọi là độ chính xác một nửa . Cách mặc định mà các mô hình deep learning được đào tạo và lưu trữ là hoàn toàn chính xác. Chuyển đổi được sử dụng phổ biến nhất là từ độ chính xác hoàn toàn sang định dạng int8.
Lượng tử hóa có thể đồng nhất hoặc không đồng nhất . Trong trường hợp thống nhất, ánh xạ từ đầu vào đến đầu ra là một hàm tuyến tính dẫn đến các đầu ra có khoảng cách đều nhau cho các đầu vào có khoảng cách đều nhau. Trong trường hợp không đồng nhất, ánh xạ từ đầu vào đến đầu ra là một hàm phi tuyến tính nên các đầu ra sẽ không cách đều nhau đối với đầu vào đồng nhất.
Đi sâu vào loại thống nhất, hàm ánh xạ tuyến tính có thể là một thao tác chia tỷ lệ và làm tròn. Do đó, lượng tử hóa đồng đều liên quan đến hệ số tỷ lệ S trong phương trình.
Khi chuyển đổi từ float16 sang int8, hãy lưu ý rằng chúng ta luôn có thể giới hạn ở các giá trị trong khoảng từ -127 đến cộng 127 và đảm bảo rằng số 0 của đầu vào ánh xạ hoàn hảo đến số 0 của đầu ra dẫn đến ánh xạ đối xứng và do đó lượng tử hóa này được gọi là đối xứng lượng tử hóa .
Mặt khác, nếu các giá trị ở hai bên số 0 không giống nhau, chẳng hạn như giữa -128 và +127. Ngoài ra, nếu chúng ta ánh xạ số 0 của đầu vào sang một số giá trị khác khác 0 ở đầu ra thì nó được gọi là lượng tử hóa bất đối xứng . Vì bây giờ chúng ta có giá trị 0 được dịch chuyển ở đầu ra, nên chúng ta cần tính giá trị này trong phương trình của mình bằng cách đưa hệ số 0, Z , vào phương trình.
Để tìm hiểu cách chúng ta có thể chọn hệ số tỷ lệ và điểm 0, chúng ta hãy lấy một ví dụ đầu vào được phân bổ như hình trên trong trục số thực. Hệ số tỷ lệ về cơ bản chia toàn bộ phạm vi đầu vào này từ giá trị tối thiểu r_min đến giá trị tối đa r_max thành các phân vùng thống nhất. Tuy nhiên, chúng tôi có thể chọn cắt bớt đầu vào này tại một thời điểm nào đó, chẳng hạn như alpha cho giá trị âm và beta cho giá trị dương. Bất kỳ giá trị nào ngoài alpha và beta đều không có ý nghĩa vì nó ánh xạ tới cùng một đầu ra như alpha. Trong ví dụ này, đó là -127 và +127. Quá trình chọn các giá trị cắt này là alpha và beta và do đó phạm vi cắt được gọi là hiệu chuẩn .
Để ngăn việc cắt quá mức, tùy chọn đơn giản nhất có thể là đặt alpha bằng r_min và beta bằng r_max. Và chúng ta có thể vui vẻ tính toán hệ số tỷ lệ S bằng cách sử dụng các giá trị r_min và r_max này. Tuy nhiên, điều này có thể khiến đầu ra không đối xứng. Ví dụ: r_max trong đầu vào có thể là 1,5 nhưng r_min chỉ có thể là -1,2. Vì vậy, để hạn chế lượng tử hóa đối xứng, chúng ta cần alpha và beta là giá trị tối đa của cả hai và tất nhiên đặt điểm 0 là 0.
Lượng tử hóa đối xứng chính xác là những gì được sử dụng khi lượng tử hóa các trọng số mạng thần kinh vì các trọng số được huấn luyện đã được tính toán trước trong quá trình suy luận và sẽ không thay đổi trong quá trình suy luận. Việc tính toán cũng đơn giản hơn so với trường hợp bất đối xứng vì điểm 0 được đặt thành 0.
Bây giờ chúng ta hãy xem lại một ví dụ trong đó đầu vào bị lệch sang một hướng, chẳng hạn như theo hướng tích cực. Điều này giống với kết quả đầu ra của một số hàm kích hoạt thành công nhất như ReLU hoặc GeLU. Trên hết, đầu ra của kích hoạt thay đổi theo đầu vào. Ví dụ, đầu ra của hàm kích hoạt khá khác nhau khi chúng ta hiển thị hai hình ảnh của một con mèo. Vì vậy, câu hỏi bây giờ là “Khi nào chúng ta hiệu chỉnh phạm vi lượng tử hóa?” Có phải trong quá trình đào tạo? Hoặc trong quá trình suy luận và khi chúng ta lấy dữ liệu để dự đoán?
Câu hỏi này dẫn đến các chế độ lượng tử hóa khác nhau, đặc biệt là trong Lượng tử hóa sau đào tạo (PTQ). Trong PTQ, chúng tôi bắt đầu với một mô hình được đào tạo trước mà không tiến hành đào tạo bổ sung. Dữ liệu quan trọng cần có từ mô hình bao gồm dữ liệu hiệu chuẩn, được sử dụng để tính toán phạm vi cắt và sau đó là hệ số tỷ lệ (S) và điểm 0 (Z). Thông thường, dữ liệu hiệu chuẩn này được lấy từ trọng lượng của mô hình. Sau quá trình hiệu chỉnh, chúng ta có thể tiến hành lượng tử hóa mô hình, thu được mô hình lượng tử hóa.
Trong Đào tạo nhận thức lượng tử hóa hay viết tắt là QAT, chúng tôi lượng tử hóa mô hình được đào tạo bằng quy trình chuẩn nhưng sau đó tinh chỉnh hoặc đào tạo lại thêm, sử dụng dữ liệu đào tạo mới để có được mô hình lượng tử hóa. QAT thường được thực hiện để điều chỉnh tham số của mô hình nhằm khôi phục độ chính xác bị mất hoặc bất kỳ số liệu nào khác mà chúng tôi quan tâm trong quá trình lượng tử hóa. Vì vậy, QAT có xu hướng cung cấp các mô hình tốt hơn lượng tử hóa sau đào tạo.
Để thực hiện tinh chỉnh, mô hình phải có khả năng phân biệt. Nhưng hoạt động lượng tử hóa là không khả vi. Để khắc phục điều này, chúng tôi sử dụng các bộ lượng tử hóa giả như các bộ ước tính xuyên suốt. Trong quá trình tinh chỉnh, các công cụ ước tính này ước tính sai số lượng tử hóa và các sai số này được kết hợp cùng với sai số huấn luyện để tinh chỉnh mô hình nhằm đạt hiệu suất tốt hơn. Trong quá trình tinh chỉnh, các bước tiến và lùi được thực hiện trên mô hình lượng tử hóa ở dạng dấu phẩy động. Tuy nhiên, các tham số được lượng tử hóa sau mỗi lần cập nhật gradient.
Hãy xem video bên dưới giải thích lượng tử hóa mô hình trong học sâu
Điều đó bao gồm khá nhiều điều cơ bản về lượng tử hóa. Chúng tôi bắt đầu với nhu cầu lượng tử hóa và các loại lượng tử hóa khác nhau như đối xứng và bất đối xứng. Chúng tôi cũng nhanh chóng tìm hiểu cách chọn tham số lượng tử hóa—cụ thể là hệ số tỷ lệ và điểm 0. Và chúng tôi đã kết thúc với các phương thức lượng tử hóa khác nhau. Nhưng tất cả được triển khai như thế nào trong PyTorch hoặc TensorFlow? Chuyện đó dành cho một ngày khác. Tôi hy vọng video này cung cấp cho bạn một số hiểu biết sâu sắc về Lượng tử hóa trong Học sâu.
Tôi hy vọng được gặp bạn trong lần tiếp theo của tôi. Cho đến lúc đó, hãy bảo trọng!