跳至內容

從零開始學 AI 工程(三):
Phase 0-3 GPU 配置與雲端

簡易理解GPU/CPU加速運算的差異和基本設置

我是 AI 工程的初學者,正透過《AI Engineering from Scratch》課程自學,並全程搭配 AI 輔助:一步步照著課程開發者的進度動手執行,卡關時就向 AI 提問、請它引導。這篇文章,是把我與 AI 互動的完整過程與學習歷程,先交由 AI 記錄、統整成初稿,再由我親自逐段審視、修改、優化而成。AI 負責整理,最終判斷與文字由我把關。

寫下它有兩個用意:替後來想走同一條路的人留一份參考,也幫自己複習、把學過的東西沉澱下來。

這篇怎麼讀

這篇跟前面幾課的格式一樣,每一步我都寫了三塊:

  • 作者要我做什麼 — 原始指令
  • 背後的道理 — 我問 AI 之後理解的白話版
  • 走到這裡才會知道的事 — 按著課程走、但作者沒明說的補充

這一課跟前面不太一樣,偏概念,動手的部分主要是在 Google Colab 上跑一段基準測試。 我是 Mac 使用者、沒有 NVIDIA 顯卡,所以這一課的實作全部在雲端完成,我的電腦只是開網頁的遙控器。

我的規則還是同一條:每一個指令,都要問到懂為止,才往下走。

這一課導覽框

  • 課名:Phase 0 · Lesson 3 — GPU 配置與雲端
  • 目標:搞懂 GPU 為什麼快、用 Colab 跑第一次基準測試、學會估算顯卡塞得下多大模型
  • 時間:課程標約 45 分鐘,我含理解大概花了一個多小時
  • Mac 使用者最重要的一句:Mac 沒有 NVIDIA 顯卡,torch.cuda.is_available() 永遠是 False,這是正常的。實作直接去 Google Colab 做
  • 完課驗證:在 Colab 上看到 CPU vs GPU 的加速倍數,跑出 VRAM 估算結果

先看懂作者的地圖:為什麼 AI 需要 GPU

課程開頭說了一句很有感的話:

Training on CPU is fine for learning. Training for real needs a GPU.

用 CPU 學習沒問題。但要玩真的訓練,需要 GPU。

這不是隨便說說。課程給了一個數字:同一個訓練任務,CPU 要跑 8 小時,GPU 只要 10 分鐘。

改考卷的類比

我問 AI 怎麼理解 CPU 和 GPU 的差別,它給了一個很好懂的類比。

CPU 像一位超級聰明的老師:什麼題目都會改,速度也快,但一次只能改一份,頂多同時改幾份(現代 CPU 有幾個到十幾個核心)。

GPU 像一間坐了幾千個工讀生的教室:每個工讀生沒老師聰明,只會做「簡單重複的算術」,但幾千個人同時動手。改考卷這種「同一個動作重複幾千次」的工作,教室完勝老師。

而深度學習的本質,剛好就是海量的矩陣乘法,就是那種「同一種乘加算術重複幾百萬次」的活兒。GPU 幾千個核心同時算,速度直接碾壓 CPU。這個類比讓我一下就抓到重點了。

三個選項,Mac 用戶怎麼選

課程列了三條路:

選項費用設定適合
本機 NVIDIA GPU免費(你已經有)裝 CUDA + cuDNN常態使用、大資料集
Google Colab 免費版免費不用設定快速實驗、家裡沒 GPU
雲端 GPU(Lambda、RunPod)每小時 $0.20–2.00SSH + 安裝認真訓練、大模型

我是 Mac,第一條路直接跳過,沒有 NVIDIA 卡。第三條路是之後 Colab 不夠用了才考慮。所以我走第二條:Google Colab,免費、不用設定、開網頁就有一張 T4 GPU 可以用。

課程也補了一句讓我安心的話:

No GPU? No problem. Most lessons work on CPU.

沒有 GPU?沒關係。大部分課程在 CPU 上就能跑。

Phases 1 到 3 的課都可以用 CPU 跑完。真正需要 GPU 加速是 Phase 4 以後的事。


步驟 1:在 Google Colab 拿到一張 GPU

作者要你做什麼

課程的指令很簡潔:

  1. colab.research.google.com
  2. Runtime > Change runtime type > T4 GPU
  3. !nvidia-smi 驗證

每行在做什麼

前兩步是用網頁介面操作,第三步是一行指令:

  • !nvidia-smi:問這台雲端機器「你有沒有 NVIDIA 顯卡?有的話報告一下狀態」。nvidia-smi 是 NVIDIA 出的系統管理工具,全名 System Management Interface。前面加 ! 是 Colab 的語法,代表「這不是 Python,是直接對作業系統下指令」

那張表在講什麼

跑完 !nvidia-smi 會跑出一張表,只需要看三個東西:

GPU Name: Tesla T4 — 拿到的顯卡型號。T4 是 Google 免費給 Colab 用戶的,性能足夠學習用。

Memory: 0MiB / 15360MiB — 這張卡有 15360 MiB(約 15 GB)的 VRAM(顯卡記憶體),目前用了 0,因為還沒跑任何運算。

GPU-Util: 0% — GPU 目前閒置中。

其他像 Driver Version、Fan、Temp 那些欄位是給管理 GPU 伺服器的工程師看的,現階段不用管。這一步就是「開工前先點名,確認工人(GPU)有到場、狀態正常」。

Colab 就是一台借來的遠端電腦,透過網頁開一個 Python 筆記本用它的 GPU。寫的東西 99% 是普通的 Python,跟在自己電腦上跑一模一樣。唯一的 Colab 專屬語法就是 ! 開頭的指令,碰到的時候知道就好。


步驟 2:CPU vs GPU 基準測試

作者要我們做什麼

import torch
import time

size = 5000

a_cpu = torch.randn(size, size)
b_cpu = torch.randn(size, size)

start = time.time()
c_cpu = a_cpu @ b_cpu
cpu_time = time.time() - start
print(f"CPU: {cpu_time:.3f}s")

if torch.cuda.is_available():
    a_gpu = a_cpu.to("cuda")
    b_gpu = b_cpu.to("cuda")

    torch.cuda.synchronize()
    start = time.time()
    c_gpu = a_gpu @ b_gpu
    torch.cuda.synchronize()
    gpu_time = time.time() - start
    print(f"GPU: {gpu_time:.3f}s")
    print(f"Speedup: {cpu_time / gpu_time:.0f}x")

每行在做什麼

  • import torch:引入 PyTorch,這是目前最主流的深度學習工具,負責處理張量(tensor)運算
  • import time:引入 Python 內建的計時工具
  • size = 5000:設定矩陣大小,5000x5000,夠大才看得出差距
  • torch.randn(size, size):隨機產生一個 5000x5000 的矩陣,裡面塞滿隨機數字
  • a_cpu @ b_cpu@ 是矩陣乘法的運算符號,讓兩個大矩陣相乘
  • time.time():記錄當下時間,算完再記一次,兩次相減就是花了多久
  • .to("cuda"):把資料從 CPU 的記憶體搬到 GPU 的記憶體(VRAM)。GPU 不能直接讀 CPU 的資料,要先搬過去才能算
  • torch.cuda.synchronize():等 GPU 真的算完才停錶。GPU 是非同步的,你叫它算,它先答應但可能還在背景慢慢做。如果不等,你會量到一個假的超快時間
  • f"CPU: {cpu_time:.3f}s":把結果印出來,.3f 代表小數點留三位

在 Colab 上跑,比的是什麼

我一開始以為是拿我 Mac 的 CPU 去對 Colab 的 GPU,後來才搞懂:在 Colab 上跑這段測試,比的是「Colab 這台雲端機器的 CPU 對上 Colab 的 T4 GPU」。整組運算都在 Google 的機器上發生,我的 Mac 只負責開網頁。同一台機器、同樣的資料,比較才公平。

我的實測結果

第一次跑:CPU 約 1.97 秒,GPU 約 0.21 秒,加速約 9 倍。 第二次跑同一格(不改任何東西):GPU 掉到 0.088 秒,加速約 22 倍。

我問 AI 為什麼第二次快這麼多。原來 GPU 第一次跑的時候,它不只是在「算」,還在做一堆準備工作:把 CUDA 的核心程式載入、幫運算編譯成 GPU 看得懂的指令、分配記憶體空間。這些事只有第一次需要做,做完就快取起來了。

AI 給了一個類比:第一次去一間新餐廳,要找路、找停車位、看菜單研究半天,整頓飯花了兩小時。第二次去同一間,路熟了、車位知道停哪、菜也知道要點什麼,半小時就吃完了。煮菜的時間沒變,變的是那些一次性的前置作業。所以第二次的數字才比較接近 GPU 的真實能力。

走到這裡才會知道的事:Colab 的格子操作

我第一次用 Colab,在打程式碼的時候不小心按到 Shift + Enter,結果程式碼直接跑掉了,還自動跳到一個新的空格子。後來才搞清楚:按 Enter 是換行,按 Shift + Enter 才是執行。

不過就算把程式碼拆成好幾個格子分開跑,也不會出事。Colab 的格子之間共享記憶體,只要按照順序從上往下跑,上面格子產生的變數,下面的格子可以直接用。


步驟 3:估算這張卡塞得下多大的模型

作者要你做什麼

課程的 Exercise 3 要你算 VRAM 能裝多大的模型:

props = torch.cuda.get_device_properties(0)
vram_gb = props.total_memory / 1e9
params_billion = (vram_gb * 1e9 / 2) / 1e9
print(f"這張 GPU 有 {vram_gb:.1f} GB VRAM")
print(f"fp16 估算最多塞得下約 {params_billion:.0f}B 參數的模型")

每行在做什麼

  • torch.cuda.get_device_properties(0):跟 GPU 說「把你的規格報告給我」,結果存進 props
  • props.total_memory / 1e9:從報告裡拿出記憶體數字,除以 10 億把 bytes 換成 GB
  • (vram_gb * 1e9 / 2) / 1e9:這裡的 / 2 就是 fp16 口訣的核心,一個參數佔 2 bytes,所以總 bytes 除以 2 就是塞得下幾個參數,最後再除以 10 億換成「B(billion)」的單位
  • print(f"..."):把結果印出來,{vram_gb:.1f} 是小數點留一位,{params_billion:.0f} 是不留小數點

什麼是「參數」、什麼是 fp16

參數:AI 問我怎麼理解這個,它說可以把 AI 模型想成一個超大的決策機器,裡面有幾十億個旋鈕。每個旋鈕存一個數字,這些數字決定了模型遇到輸入時怎麼反應。旋鈕越多,模型通常越聰明,但也越佔記憶體。 像 Meta 的 Llama 有 8B(80 億個旋鈕)和 70B(700 億個旋鈕)的版本。

fp16:每個旋鈕要存一個數字,數字在電腦裡要佔空間。用 fp32(32 位元,4 bytes)存比較精準但很佔空間;用 fp16(16 位元,2 bytes)存,精準度只掉一點點,空間省一半。現在業界大部分都用 fp16 甚至更小的格式,因為夠用了。

所以口訣是:一個參數大約佔 2 bytes(fp16)

實際算一次

T4 有約 15 GB VRAM,換算成 bytes 大約 150 億。每個參數佔 2 bytes,150 億除以 2 等於 75 億個參數,大約 7.5B。

這代表什麼?如果之後想在這張免費的 T4 上跑一個語言模型,Llama 8B 勉強塞得下,但 Llama 70B 完全不可能。光是把模型放進記憶體就放不下,更別說跑。就像一個 15 公升的背包,塞得下一台筆電,但塞不下一台電視。

這個「VRAM 多大就能跑多大的模型」的直覺,AI 說之後選模型、選雲端方案的時候會一直用到。


四個關鍵詞

課程結尾給了一張對照表,我整理成白話版:

術語一般人怎麼講白話意思
CUDA「GPU 程式設計」NVIDIA 專屬的技術,讓程式可以跑在 GPU 上。只認 NVIDIA 的卡,所以 Mac 沒有
VRAM「GPU 記憶體」顯卡自己的記憶體,跟你電腦的 RAM 分開。它的大小決定你能跑多大的模型
fp16「半精度」用 16 位元存一個數字,比一般的 32 位元省一半空間,準確度幾乎不掉
Tensor Core「快速矩陣硬體」GPU 裡面專門加速矩陣乘法的特殊零件,比普通核心再快 4 到 8 倍