# 【vMaker Edge AI專欄 #02】 要玩AI前,先來認識數字系統
作者:Jack OmniXRI, 2023/02/13
![](https://i.imgur.com/aDr5vuI.jpg)
對於剛入門如Arduino這類單晶片或樹莓派這類單板微電腦的朋友,最常遇到的問題就是如何接入各種感測器信號及推動可變速度的馬達或可變亮度的燈具,而這正是開發各種智能感測器(Smart Sensors)及邊緣智能裝置(Edge AI Devices)的基礎。
為了讓大家後續能更順利開發智慧物聯網(AI + Internet of Things, AIoT)及微型機器學習(Tiny Machine Learning, TinyML)相關裝置,接下來會先從類比、數位系統的關係開始介紹,再來會說明數位系統是如何表示整數及小數,最後會詳解AI模型訓練和推論常用的數字系統及最新AI專用的數字系統,以便幫大家建立好玩AI前的基本功。
## 1. 類比與數位系統
在真實世界中信號是連續的,又可稱為類比(Analog)信號。而在大多數電子晶片(積體電路)上運行的是不連續(有限取樣頻率)且不精細(有限分解能力)的數位(Digital)信號。因此要讓電子晶片了解(Input)及改變(Output)世界就要仰賴類比數位轉換(Analog to Digital Convert, ADC)及數位類比轉換(Digital to Analog Convert, DAC)。而這兩項功能通常會被設計在單晶片(Micro Controll Unit, MCU)或微處理器(Micro Processor Unit, MPU)中,方便大家寫程式來接收、處理及輸出。
如Fig. 1上半部所示,左邊為真實世界產生的連續信號(如聲音、振動、溫濕度等),經過類比感測器(Sensors)擷取信號並轉換成電壓。有時信號太小,還需要將其放大至能處理的大小(如0 ~ 5V, -10 ~ +10V等),方便後續處理。接著就要進行類比數位轉換(ADC),以指定頻率(每秒取多少次)、分解能力(如8位元,2^8=256階)進行取樣(Sampling),如此便可得到對應的數位信號。以對聲音為例,假設一秒取16,000次樣本(16KHz),每筆信號以8位元進行分解(256階),則取一秒就會產生16KByte(16K x 8 bit)的原始資料。若嫌分解能力不足,可增加至10位元(2^10=1024階)甚至更高位元數,但代價就是要使用更多的資料儲存空間。
當轉換成數位信號時,就能方便進行計算、顯示、傳輸及後續控制用途。如Fig. 1下半部所示,單晶片或微處理器若想要調整馬達轉速或燈具亮度等這些類比控制裝置時,此時就需使用到數位類比轉換(DAC)。一般來說會將指定的數位位元數(如4/8/16位元)合成一個指定電壓輸出範圍,如0 ~ 5V, -10 ~ +10V等。合成時則依不同需求指定合成頻率,如每秒1次(1Hz)或像喇叭播放音樂的16K~44KHz。
由於DAC需佔用較多的位元數且不利整合進純數位邏輯的單晶片或微處理器中,因此目前較多使用數位輸出的接腳配合脈波寬度調變(Pulse Width Modulation, PWM)來代替,只需使用二個計時器,一個負責工作週期,一個負責工作寬度,就能合成一個類比輸出功能。其原理為改變輸出工作(Duty)時間佔比,如此便能得到不同電壓輸出,但缺點是會產生一定頻率的干擾,不適用需要穩定直流電壓的應用。
![](https://i.imgur.com/VvOjDgC.jpg)
Fig. 1 類比與數位轉換關係圖。(OmniXRI整理製作, 2023/02/13)
## 2. 數位系統如何表示數字
一般日常生活中大家都是使用十進制(Decimal,簡寫DEC),0到9的數字系統,但對電腦或數位邏輯計算而言,它只認得二進制(Binary,簡寫BIN),就是0和1。因此在數位系統開發上需了解其轉換方式,才不會一頭霧水。另外由於二進制在表示大數字時所需位數太多,不利於人類讀寫,所以常會使用十六進制(Hexadecimal, HEX)來表示,讓四個BIN的位元變成一個HEX的位元,而每個位元使用0到9加上A到F來代表0到15的數字。從Fig. 2可簡單了解各種進制其實就是基底(Base)數字加上指數(Exponent)所組合成的。而要將十進制轉成二進制(或N進制)則僅需使用短除法就能輕易獲得。
![](https://i.imgur.com/v9sgU2F.jpg)
Fig. 2 不同進制數字表示方式及轉換方式。(OmniXRI整理製作, 2023/02/13)
## 3. 整數與小數
有了二進制數字概念後,接著我們要更深入了解在數位系統中,如何表示整數(正整數、負整數)及小數(定點數及浮點數)。
### 3.1 整數(Integer)
一般為了方便積體電路處理二進制計算及程式開發,通常會使用2的N次方位元數(bit)做為一個單位來進行處理,如 8/16/32/64 Bit等。如Fig. 3左半部份即為常見的C/C++語言用於表示的名稱、Byte數及能表達的整數數值範圍。由於早期的MCU/MPU CPU位元數較小(8/16 bit),因此在不同硬體上進行程式開發時,int有時代表16 bit(short int),有時代表32 bit(long int, long),為了避免搞混,有些程式開發工具會另外定義成int8, int16, int32, int64等新的名稱以利區分,而這樣的表示方式也延用到現在常見的AI權重(Weights)數值的表示方式。
另外為了能表達負整數,於是將最高位元(MSB)定為負數符號(Sign),而其餘位元數則表示整數。常見的有最高位元、1的補數及2的補數表示法,如Fig.3 右半部所示。最高位元法,即最高位元(符號)為1時表示負整數,其餘位元依正整數表示方式,但缺點是會有+0(00000000)和-0(10000000)的問題產生。1的補數法,即將所有位元相反來表示負數,但同樣會有+0(00000000)和-0(111111111)問題產生。為解決+0和-0同時存問題,於是有了2的補數系統產生,即先求出1的補數再加1來決解,如圖Fig. 3左下所示。
![](https://i.imgur.com/XQlKNaj.jpg)
Fig. 3 整數常用名稱及表示範圍及負整數表示法。(OmniXRI整理製作, 2023/02/13)
### 3.2 定點數(Fixed Point)
為了能擴大數字表達範圍及更精密的小數點數字,於是就有人提出把整數除上一個固定值來表達,而這個固定值最好是基數的N次方,如此就相當於把小數點左移N位。以十進位的123.456為例,就可以使用123,456除上10的3次方(即1,000)便可得到。使用定點數的好處是計算量小,但缺點是小數的位數有限,能表示的動態範圍有賴整數和小數位數的配比。
以同樣方式亦能擴展到二進制,如Fig. 4上半部所示,假設將原有的16 bit整數變成1 bit正負符號,10 bit整數,5 bit小數,則對應十進制時整數部份最大可表示範圍為-1024到+1023,而小數部份最小分解能力則為1/32(即1/2^5 = 0.03125),約為小數點後五位。當整數變為1bit,小數14 bit時,則小數最小分解能力為1/8192(即0.0001220703125),約為小數點後13位。但這樣的方式對應到十進制小數點時,會有些許誤差產生,導致能正確表示的位數會更少。
![](https://i.imgur.com/YefZlRC.jpg)
Fig. 4 二進制定點數與浮點數表示法。(OmniXRI整理製作, 2023/02/13)
### 3.3 浮點數(Float Point)
為了解決整數及小數表達範圍不夠大、不夠精準的問題,IEEE 754制定了二進位浮點數算術標準[1],方便各種硬體都能統一浮點數的表示方式,而這種方式較接近一般科學記號數字表示方式,有一個實數(通常小於1或整數部份最多為1位數)再乘上一個10的N次方的數字(通常以小寫e表示10的冪次)。如Fig.4下半部所示,目前常用的有半精度(FP16)、單精度(FP32)及雙精度(FP64)浮點數表示法,即使用16/32/64 bit來表示帶有小數的數值。IEEE 754所定義的浮點數組成方式主要分為三個部份,最高位元為正負符號、接著為指數,最後為小數部份,依不同精度指數、小數部份位數及數值可表示範圍如下所示。
* **半精度(FP16):** 符號1 bit,指數5 bit,小數10 bit,數值表示範圍 ±5.96e−8 ~ 65504。
* **單精度(FP32):** 符號1 bit,指數8 bit,小數23 bit,數值表示範圍 ±1.18e-38 ~ ±3.40e38。
* **雙精度(FP64):** 符號1 bit,指數11 bit,小數52 bit,數值表示範圍 ±2.23e-308 ~ ±1.80e308。
## 4. AI新數字系統
現有AI應用大多都是使用深度學習及神經網路,而隨著網路的深度(層數)增加,所需的神經元和權重值數量也隨之暴增。為了提高模型訓練成果的精確度,通常會使用浮點數FP32(4 Byte)作為權重值的表示方式。而當部署到推論裝置時,為了減少權重儲存空間及加快推論速度,經常會將數值精度降至FP16(2 Byte)甚從浮點數降到整數INT8(1 Byte),但缺點就是會損失一點推論精確度。
如Fig. 5所示,由於FP32和FP16表達指數的位元數不同,因此在轉換時沒有特殊硬體協助下會增加一些時間,因此Google推出BF16格式,讓指數部份位數和FP32相同皆為8 bit,而尾數部份則只保留10 bit,如此FP32在轉換時可直接去除尾部16 bit即可,大幅加快處理速度,但缺點是數值能表達的精細度有損失不少。後來Nvidia推出Tensor Float TF32格式,取FP32的指數範圍(8bit)和FP16的尾數精度(10 bit)兩者的優點進行整合,但缺點是合計要19 bit,和數位系統常用的16 bit不一致,只能透過Nvidia專用的硬體來實現,無法在其它硬體上完成。
另外由於INT8用於推論時能表現的數值範圍只能在 -127 ~ +128或0 ~ 255之間,難以精準表達權重值的微小差異,因此最近開始有人提出FP8格式[2],採用符號1 bit,指數5 bit,尾數2 bit(e5m2)或指數4 bit,尾數3 bit(e4m3)格式,前者指數位數高,尾數位數少,動態範圍較大,數值表示精細度較差,適合用於訓練,而後者指數位數少,尾數位數多,適合用於推論。當混合使用時就能得到高位元浮點數的效果,也能讓計算浮點數的硬體不用去遷就整數計算用的硬體,以提升運算效能。
![](https://i.imgur.com/DLMN2SB.jpg)
Fig. 5 AI常用二進制浮點數表示法。(OmniXRI整理製作, 2023/02/13)
## 5. 小結
在充份了解各種數位系統數字表示法後,相信大家對於未來在使用ADC接收感測器信號、利用DAC, PWM控制可變致動元件都能更清楚這些數值背後的意義。待未來整合AI應用時,就能更加理解如何以適當的數字系統完成更精確、更快速地運行模型進行推論。
## 參考文獻
[1] Wikipedia, IEEE754 二進位浮點數算術標準
https://zh.wikipedia.org/zh-tw/IEEE_754
[2] Paulius Micikevicius et al., "FP8 Formats for Deep Learning"
https://arxiv.org/abs/2209.05433
**本文同步發表在[【台灣自造者 vMaker】](https://vmaker.tw/)**
---
OmniXRI 整理製作,歡迎點贊、收藏、訂閱、留言、分享,
###### tags: `vMaker` `Edge AI`