dede網(wǎng)站主頁打不開怎么制作網(wǎng)頁教程
塊浮點(Block Floating-Point, BFP)
是一種數(shù)據(jù)表示方法,它結(jié)合了傳統(tǒng)浮點數(shù)和整數(shù)量化的優(yōu)勢,特別適用于深度學(xué)習(xí)應(yīng)用中以提高計算效率和減少存儲需求。在BFP格式中,一組數(shù)值共享同一個指數(shù)部分,而每個數(shù)值的尾數(shù)則獨立保存。這意味著,在一個塊內(nèi)的所有數(shù)字都使用相同的縮放因子,這與傳統(tǒng)的浮點數(shù)不同,后者為每個數(shù)值分配了一個獨立的指數(shù)。這種設(shè)計允許BFP在保持較高數(shù)值保真度的同時,顯著減少了所需的比特數(shù)。例如,在硬件實現(xiàn)中,BFP的縮放因子通常被限制為2的冪次,這樣不僅便于硬件實現(xiàn),還能有效減少異常值的影響。
進一步地,BFP通過引入兩級縮放策略來優(yōu)化其性能。首先,初始值集合根據(jù)數(shù)據(jù)分布使用較為“昂貴”的FP32重新縮放步驟進行全局縮放,形成預(yù)縮放分區(qū)。然后,這些分區(qū)可以進一步使用低成本、2的冪次表示的縮放因子進行細粒度調(diào)整。這種方法能夠在有限比特數(shù)的情況下構(gòu)建高保真度的數(shù)據(jù)表示,同時最小化計算和內(nèi)存開銷,并接近全精度縮放的效果。此外,BFP還能夠很好地集成到現(xiàn)有的標準浮點點積流水線中,這意味著它可以利用現(xiàn)有電路設(shè)計,降低邊際成本。通過這種方式,BFP不僅提高了計算效率,而且減少了量化誤差,使得模型在低比特寬度下依然能保持較高的準確性??傊?#xff0c;BFP提供了一種平衡數(shù)值精度和計算效率的有效方法,尤其適合用于需要高效處理大量數(shù)據(jù)的深度學(xué)習(xí)場景。
減少所需的比特數(shù)
塊浮點(Block Floating-Point, BFP)的設(shè)計允許在保持較高數(shù)值保真度的同時顯著減少所需的比特數(shù)。其核心思想是:一組相鄰的數(shù)值共享同一個指數(shù)(exponent),而每個數(shù)值只存儲自己的尾數(shù)(mantissa)。這種方式相比于傳統(tǒng)的浮點格式(如FP32或FP16),避免了為每個數(shù)值單獨存儲指數(shù),從而節(jié)省了大量比特。
我們通過一個具體的例子來說明:
假設(shè)我們有以下4個浮點數(shù)(以二進制科學(xué)計數(shù)法表示):
x1 = 1.0 * 2**3
x2 = 1.5 * 2**3
x3 = 0.75 * 2**3
x4 = 2.0 * 2**3
這些數(shù)的共同指數(shù)是 3,只有尾數(shù)不同。如果我們用傳統(tǒng) FP32 格式存儲這四個數(shù),每個數(shù)需要 32 bit,總共需要:
total_bits_fp32 = 4 * 32 = 128 bits
但如果使用 BFP 格式,我們可以只存儲一次公共指數(shù)(例如用 8 bits 表示),然后分別存儲每個數(shù)的尾數(shù)(例如每個尾數(shù)用 5 bits 表示),那么總比特數(shù)為:
total_bits_bfp = 8 + 4 * 5 = 28 bits
可以看到,BFP 所需的比特數(shù)僅為傳統(tǒng)浮點數(shù)的 21.9%,極大地節(jié)省了存儲空間和帶寬。
更重要的是,這種設(shè)計并沒有明顯犧牲精度。因為尾數(shù)仍然保留了足夠的位數(shù)來表示每個數(shù)值的細節(jié),只是共享了一個統(tǒng)一的指數(shù)。只要這組數(shù)值的動態(tài)范圍相近(即它們大致處于同一數(shù)量級),共享指數(shù)就不會導(dǎo)致顯著的精度損失。
再舉一個更貼近深度學(xué)習(xí)的例子:
在神經(jīng)網(wǎng)絡(luò)中,某一層的激活值可能如下所示:
a = [0.125, 0.25, 0.5, 1.0, 2.0, 4.0]
這些數(shù)的指數(shù)都在 2?3 到 22 之間。如果我們選擇一個合適的公共指數(shù)(比如取最大指數(shù) e = 2
),然后對所有數(shù)值進行縮放,可以得到:
scaled_a = [0.015625 * 2**2, 0.0625 * 2**2, 0.125 * 2**2, 0.25 * 2**2, 0.5 * 2**2, 1.0 * 2**2]
這樣就可以用一個統(tǒng)一的指數(shù) e=2
和各自的尾數(shù)來表示整個數(shù)組,進一步壓縮數(shù)據(jù)表示的位寬。
綜上所述,塊浮點(BFP)通過共享一組數(shù)值的指數(shù)部分,顯著減少了總的比特數(shù),同時又通過獨立存儲每個數(shù)值的尾數(shù),保留了足夠的數(shù)值精度。這種方法特別適用于深度學(xué)習(xí)等大規(guī)模并行計算場景,在保證模型性能的前提下,大幅提升了硬件效率和內(nèi)存利用率。
MX
塊浮點(Block Floating-Point, BFP)和共享微指數(shù)(Shared Microexponents, MX)都是為了解決深度學(xué)習(xí)中高效計算和存儲的需求而設(shè)計的數(shù)據(jù)表示方法,但它們在實現(xiàn)細節(jié)上有所不同。BFP允許一組數(shù)值共享同一個指數(shù)部分,而每個數(shù)值的尾數(shù)則獨立保存,從而減少了存儲單獨指數(shù)所需的空間。相比之下,MX格式進一步細化了這種概念,通過引入硬件支持的細粒度縮放因子來減少數(shù)值噪聲,并優(yōu)化硅片成本。
具體來說,在BFP中,假設(shè)我們有n個數(shù)x?, x?, ..., x?
,可以表示為:
# 假設(shè)有n個數(shù),表示如下:
x = [m1 * 2**e for m1 in range(1, n+1)]
# 其中mi是尾數(shù),e是公共指數(shù)。
# 如果使用傳統(tǒng)浮點表示法,每個數(shù)需要32位,總共需要:
total_bits_fp32 = 32 * n# 使用BFP格式時,我們只需要一個公共指數(shù)(例如8位),以及每個數(shù)的獨立尾數(shù)(假設(shè)每個尾數(shù)需要5位)
public_exponent_bits = 8
mantissa_bits_per_number = 5
total_bits_bfp = public_exponent_bits + mantissa_bits_per_number * n
然而,MX格式采用了更加細粒度的縮放策略。它不僅共享一個全局的指數(shù),還為每個小分塊內(nèi)的數(shù)值分配了一個額外的微指數(shù)。這意味著MX格式能夠更精確地調(diào)整每個數(shù)值的實際大小,減少量化誤差。以MX為例,其數(shù)據(jù)塊由一個共享尺度X和k個標量元素{P?}組成,每個元素表示為XP?
。這里的關(guān)鍵在于MX格式中的每個元素可以根據(jù)需要應(yīng)用不同的微指數(shù),從而更好地適應(yīng)數(shù)據(jù)分布的變化。例如:
# 假設(shè)有一個MX塊,包含4個元素,每個元素的表示如下:
element_values = [v1, v2, v3, v4]
# 共享尺度X
shared_exp = 3 # 示例值
X = 2 ** shared_exp
# 每個元素的值為 XPi,其中Pi是根據(jù)元素數(shù)據(jù)格式進行量化后的結(jié)果
P = [0.125, 0.25, 0.5, 1.0] # 示例值
values_in_mx_format = [X * p for p in P]# 對于MX格式,每個塊都有一個共享的指數(shù)X和多個標量元素Pi
# 例如,對于一個具體的MX塊,我們可以定義如下:
block_size = 4
scale_data_format = 'E8M0' # 示例格式
element_data_format = 'FP8(E4M3)' # 示例格式
elements = [0.125, 0.25, 0.5, 1.0] # 示例元素值# 將這些元素轉(zhuǎn)換為MX格式
def convert_to_mx_format(elements):max_val = max(abs(v) for v in elements)shared_exp = int(max_val).bit_length() - 1 # 簡化處理X = 2 ** shared_expPi = [v / X for v in elements]return X, PiX, Pi = convert_to_mx_format(elements)
print(f"共享尺度X: {X}, 元素值Pi: {Pi}")
MX格式的一個顯著特點是它可以在不犧牲模型準確性的前提下,顯著減少所需的比特數(shù),并提高硬件效率。這是因為MX格式能夠提供比BFP更高的數(shù)值保真度,特別是在處理具有較大動態(tài)范圍的數(shù)據(jù)集時。此外,MX格式利用硬件支持的微指數(shù)來自動設(shè)置所有縮放因子,無需復(fù)雜的軟件干預(yù)。
因此,盡管BFP和MX都旨在通過共享指數(shù)來優(yōu)化數(shù)據(jù)表示,MX通過引入更細粒度的縮放機制,進一步提高了數(shù)值精度和硬件效率。這使得MX格式在AI硬件加速電路中尤為重要,因為它能夠在保持或接近原有模型準確性的同時,大幅降低計算和存儲需求。正因為如此,支持MX格式的AI硬件加速電路對于現(xiàn)代深度學(xué)習(xí)系統(tǒng)的性能提升至關(guān)重要。
綜上所述,MX與BFP相比,不僅繼承了共享指數(shù)的優(yōu)點,還通過細粒度的微指數(shù)調(diào)整,提供了更高的靈活性和精度,使其成為高效AI硬件設(shè)計的理想選擇。
細粒度
好的,讓我們通過一個具體的例子來詳細解釋 MX(Microscaling) 的流程,并展示細粒度縮放的過程。我們將使用一組具體的數(shù)值,并通過代碼逐步演示如何將這些數(shù)值轉(zhuǎn)換為 MX 格式。
具體例子
假設(shè)我們有一個包含4個浮點數(shù)的列表 elements
:
elements = [0.125, 0.25, 0.5, 1.0]
我們將通過以下步驟將其轉(zhuǎn)換為 MX 格式,并展示細粒度縮放的過程。
步驟一:找出最大值
首先,我們需要找出 elements
列表中絕對值最大的元素。
max_val = max(abs(v) for v in elements)
# 對于 elements = [0.125, 0.25, 0.5, 1.0]:
# abs(0.125) = 0.125
# abs(0.25) = 0.25
# abs(0.5) = 0.5
# abs(1.0) = 1.0
# max_val = max([0.125, 0.25, 0.5, 1.0]) = 1.0
步驟二:計算共享指數(shù)
接下來,我們根據(jù)最大值 max_val
計算共享指數(shù) shared_exp
。這里我們使用簡化的方法來估算 log2(max_val)
。
shared_exp = int(max_val).bit_length() - 1
# 對于 max_val = 1.0:
# int(1.0) = 1
# 1.bit_length() = 1
# shared_exp = 1 - 1 = 0
步驟三:計算共享尺度 X
根據(jù)共享指數(shù) shared_exp
,我們可以計算共享尺度 X
。
X = 2 ** shared_exp
# 對于 shared_exp = 0:
# X = 2 ** 0 = 1.0
步驟四:計算每個元素的 Pi 值
然后,我們將每個原始值除以共享尺度 X
,得到歸一化后的值 Pi
。
Pi = [v / X for v in elements]
# 對于 elements = [0.125, 0.25, 0.5, 1.0] 和 X = 1.0:
# Pi = [0.125 / 1.0, 0.25 / 1.0, 0.5 / 1.0, 1.0 / 1.0]
# Pi = [0.125, 0.25, 0.5, 1.0]
步驟五:返回結(jié)果
最終,我們返回共享尺度 X
和歸一化后的值 Pi
。
return X, Pi
# 返回結(jié)果:X = 1.0, Pi = [0.125, 0.25, 0.5, 1.0]
細粒度縮放的例子
為了展示細粒度縮放的效果,我們假設(shè) elements
列表中的數(shù)值動態(tài)范圍更大一些。例如:
elements = [0.125, 0.25, 0.5, 8.0]
步驟一:找出最大值
max_val = max(abs(v) for v in elements)
# 對于 elements = [0.125, 0.25, 0.5, 8.0]:
# abs(0.125) = 0.125
# abs(0.25) = 0.25
# abs(0.5) = 0.5
# abs(8.0) = 8.0
# max_val = max([0.125, 0.25, 0.5, 8.0]) = 8.0
步驟二:計算共享指數(shù)
shared_exp = int(max_val).bit_length() - 1
# 對于 max_val = 8.0:
# int(8.0) = 8
# 8.bit_length() = 4
# shared_exp = 4 - 1 = 3
步驟三:計算共享尺度 X
X = 2 ** shared_exp
# 對于 shared_exp = 3:
# X = 2 ** 3 = 8.0
步驟四:計算每個元素的 Pi 值
Pi = [v / X for v in elements]
# 對于 elements = [0.125, 0.25, 0.5, 8.0] 和 X = 8.0:
# Pi = [0.125 / 8.0, 0.25 / 8.0, 0.5 / 8.0, 8.0 / 8.0]
# Pi = [0.015625, 0.03125, 0.0625, 1.0]
步驟五:返回結(jié)果
return X, Pi
# 返回結(jié)果:X = 8.0, Pi = [0.015625, 0.03125, 0.0625, 1.0]
細粒度縮放的實際應(yīng)用
現(xiàn)在,我們來看一下細粒度縮放的應(yīng)用。假設(shè)我們要將這些 Pi
值量化到 FP8(E4M3) 格式。FP8(E4M3) 表示有4位指數(shù)和3位尾數(shù)的8位浮點數(shù)。
FP8(E4M3) 示例
對于每個 Pi
值,我們需要將其量化到 FP8(E4M3) 格式。假設(shè)我們使用簡單的量化方法(實際硬件中會有更復(fù)雜的量化算法):
def quantize_to_fp8(value):# 簡單的量化方法:直接截取前幾位有效數(shù)字# 這里只是一個示意,實際實現(xiàn)會更復(fù)雜return round(value * (2 ** 3)) / (2 ** 3)quantized_Pi = [quantize_to_fp8(p) for p in Pi]
# 對于 Pi = [0.015625, 0.03125, 0.0625, 1.0]:
# quantized_Pi = [round(0.015625 * 8) / 8, round(0.03125 * 8) / 8, round(0.0625 * 8) / 8, round(1.0 * 8) / 8]
# quantized_Pi = [0.015625, 0.03125, 0.0625, 1.0]
在實際應(yīng)用中,quantize_to_fp8
函數(shù)會更復(fù)雜,但這個簡單示例展示了如何將值量化到特定格式。
總結(jié)
通過上述步驟,我們展示了如何將一組數(shù)值轉(zhuǎn)換為 MX 格式,并引入了細粒度縮放的概念。具體來說:
- 我們先找到最大值
max_val
,并計算共享指數(shù)shared_exp
。 - 根據(jù)
shared_exp
計算共享尺度X
。 - 將每個原始值除以
X
,得到歸一化后的值Pi
。 - 最后,我們將
Pi
值量化到目標格式(如 FP8(E4M3))。
這種設(shè)計使得 MX 格式能夠靈活適應(yīng)不同的數(shù)據(jù)分布,并在保持較高數(shù)值保真度的同時顯著減少了所需的比特數(shù)。相比 BFP,MX 通過細粒度縮放機制提供了更高的精度控制。
分層
在神經(jīng)網(wǎng)絡(luò)量化中,第一級塊和第二級塊是一種分層結(jié)構(gòu)。第一級塊是較大的劃分單位,而第二級塊是在第一級塊內(nèi)部進一步細分的小單位。這種結(jié)構(gòu)允許在保持整體精度的同時進行細粒度的控制。
塊粒度指的是每個塊中包含多少個數(shù)值。第一級塊粒度表示每個第一級塊包含的元素數(shù)量,第二級塊粒度表示在每個第一級塊內(nèi)部,再劃分成的更小塊的數(shù)量。
尺度位寬是指用于表示該塊縮放因子(scale)的比特數(shù)。每個塊都有一個共享的 scale,它決定了這個塊內(nèi)所有數(shù)值的動態(tài)范圍。第一級和第二級可以有不同的 scale 位寬。
尾數(shù)位寬是指每個具體數(shù)值用多少比特來表示。它決定了每個數(shù)值的精度。
下面通過一個例子來說明這些概念:
假設(shè)我們有以下配置:
k1 = 16 # 第一級塊大小為16個元素
k2 = 2 # 第二級塊大小為2個元素
d1 = 8 # 第一級 scale 使用 8-bit
d2 = 1 # 第二級 scale 使用 1-bit
m = 7 # 每個數(shù)值的尾數(shù)部分使用 7-bit 表示
在這個例子中,第一級塊包含16個元素,這些元素又被劃分為8個第二級塊,每個第二級塊包含2個元素。每個第一級塊使用8-bit來表示其scale,每個第二級塊使用1-bit來表示其scale。每個數(shù)值的尾數(shù)部分使用7-bit來表示。
我們可以計算出每個元素平均占用的比特數(shù):
average_bits_per_element = (d1 + m) / k1 + d2 / k2
# 即:
# average_bits_per_element = (8 + 7) / 16 + 1 / 2
# average_bits_per_element = 15/16 + 0.5 ≈ 0.9375 + 0.5 = 1.4375 bits per element
通過這種分級量化的設(shè)計,可以在不顯著損失精度的前提下,大幅減少模型所需存儲空間和計算資源。
分層數(shù)據(jù)
好的,下面我們將以一個具體的數(shù)值例子來說明 MX4 的兩級量化結(jié)構(gòu)。MX4 是一種混合精度量化方案,它采用兩級塊結(jié)構(gòu)(two-level block structure),并結(jié)合尺度(scale)和尾數(shù)(mantissa)來表示數(shù)值。
我們假設(shè)有一個浮點數(shù)數(shù)組 x
,其長度為 8,例如:
x = [3.14, 6.28, 9.42, 12.56, 15.7, 18.84, 21.98, 25.12]
這個數(shù)組可以看作是一個神經(jīng)網(wǎng)絡(luò)中的權(quán)重或激活值的一部分。我們希望用 MX4 格式對其進行壓縮表示。
第一步:劃分第一級塊
在 MX4 中,第一級塊大小為 k1 = 4
,因此我們可以將上面的數(shù)組劃分為兩個第一級塊:
block1_level1 = [3.14, 6.28, 9.42, 12.56]
block2_level1 = [15.7, 18.84, 21.98, 25.12]
每個第一級塊都會對應(yīng)一個第一級尺度(scale1),它是該塊中所有元素的絕對最大值。我們計算如下:
scale1_block1 = max(abs(3.14), abs(6.28), abs(9.42), abs(12.56)) = 12.56
scale1_block2 = max(abs(15.7), abs(18.84), abs(21.98), abs(25.12)) = 25.12
然后,每個元素被歸一化到 [-1, 1] 范圍內(nèi),并使用 4-bit 尾數(shù)(m=4)進行表示。歸一化公式如下:
normalized_x = x / scale1
quantized_x = round(normalized_x * (2**m - 1))
對第一個第一級塊進行歸一化與量化:
normalized_block1 = [3.14/12.56, 6.28/12.56, 9.42/12.56, 12.56/12.56]= [0.25, 0.5, 0.75, 1.0]quantized_block1 = [round(0.25 * 15), round(0.5 * 15), round(0.75 * 15), round(1.0 * 15)]= [4, 8, 11, 15] # 每個數(shù)是 4-bit 表示
同理可得第二個第一級塊的量化結(jié)果。
第二步:劃分第二級塊
接下來,在每個第一級塊內(nèi)部進一步劃分為第二級塊。MX4 中規(guī)定第二級塊大小為 k2 = 2
,所以每個第一級塊(含4個元素)被劃分為兩個第二級塊:
# block1_level1 劃分:
block1_level2_1 = [3.14, 6.28]
block1_level2_2 = [9.42, 12.56]# block2_level1 劃分:
block2_level2_1 = [15.7, 18.84]
block2_level2_2 = [21.98, 25.12]
每個第二級塊也有自己的尺度(scale2),用于局部調(diào)整。例如:
scale2_block1_1 = max(abs(3.14), abs(6.28)) = 6.28
scale2_block1_2 = max(abs(9.42), abs(12.56)) = 12.56
此時每個第二級塊內(nèi)的元素可以用更細粒度的 scale 來表示,但它們的 scale 使用 2-bit 編碼(d2=2),即只保留有限的動態(tài)范圍。
第三步:總比特消耗計算
現(xiàn)在我們統(tǒng)計一下總共用了多少比特來表示這 8 個原始浮點數(shù)。
- 第一級 scale 數(shù)量:2 個(每個 d1=4 bit) → 共 2 × 4 = 8 bits
- 第二級 scale 數(shù)量:4 個(每個 d2=2 bit) → 共 4 × 2 = 8 bits
- 所有元素的尾數(shù):8 個(每個 m=4 bit) → 共 8 × 4 = 32 bits
總計:
total_bits = 8 + 8 + 32 = 48 bits
average_bits_per_element = total_bits / 8 = 6 bits per element
總結(jié)
在這個 MX4 示例中,我們通過將原始數(shù)據(jù)劃分為兩級塊結(jié)構(gòu),分別設(shè)置了不同位寬的尺度和統(tǒng)一的尾數(shù)位寬,最終實現(xiàn)了高效的壓縮表示。雖然原始數(shù)據(jù)是 32 位浮點型,但經(jīng)過 MX4 量化后,平均每個元素僅需 6 位 存儲,節(jié)省了約 81% 的存儲空間,同時保持了較高的精度水平。這種結(jié)構(gòu)非常適合邊緣設(shè)備上的高效推理部署。