剛好實驗室有一台主機,可以拿來玩玩,在畢業前盡量使用硬體資源。

網路上已有許多教學與學習資源,這裡主要記錄自己實作的過程、遇到的問題與筆記,已確認可正常安裝並穩定使用,主要用來熟悉 Linux-based 的 OS 以及 練習一些顯卡和 Docker 的操作,並為小型的 side project 做準備,在撰寫時其實已經完成第一版了,但還有一些可以延伸繼續做的地方,這裡先放連結:

部分筆記使用 AI 協助與實際測試整理,實際步驟可能會依硬體環境而有所差異

🖥 測試平台(硬體與系統資訊)

類別 規格
作業系統 Ubuntu 24.04 LTS (Kernel 6.14)
Windows 10 專業版
CPU AMD Ryzen 5 5600X (6 Cores / 12 Threads)
記憶體 (RAM) 46 GiB
Swap 8 GiB (目前未使用)
GPU NVIDIA RTX 4090
GPU VRAM 24 GB
NVIDIA Driver 580.95
CUDA 支援版本 最高支援 CUDA 13.0

📊 Ubuntu 記憶體狀態(安裝完成後測試)

項目 數值
Total Memory 46 GiB
Used 2.6 GiB
Free 27 GiB
Buff/Cache 17 GiB
Available 44 GiB

BIOS & Windows 10 安裝

準備工作

首先先下載安裝用的 ISO 映像檔:

Ubuntu 24.04 LTS 官方 ISO

Windows 10 安裝 ISO(或既有開機 USB)


接著使用第三方工具將 ISO 製作成可開機 USB,本次使用工具:

製作時注意項目:

  • 分割區類型建議選擇:GPT
  • 目標系統類型:UEFI (非 CSM)
  • 檔案系統:FAT32(Ubuntu 通常自動設定)

如果主機板是較新的(如 ASUS ROG),基本上都是 UEFI 模式

完成後即可取得可開機 USB。

這裡記得盡量主機或顯卡不要插額外的線,我後面就是因為畫面一直灰屏找不到問題,最後才發現我有一條 VGA 的線插在顯卡的插槽,讀不到另一台 DP 轉 HDMI 的線訊號

BIOS / UEFI(ASUS ROG)

我這台電腦 BIOS 是 ASUS ROG,介面類似下圖(非實際畫面,僅供參考)。

將製作好的 USB 插入主機後:

  1. 開機按 DelF2 進入 BIOS(ASUS ROG)
  2. 進入 Boot 選項
  3. 將 USB 設為第一開機順位(或直接使用 Boot Override)
⚠ 建議檢查

BIOS 模式是否為 UEFI

Secure Boot 是否開啟(通常 Windows 可正常安裝),若未來要裝 Ubuntu + NVIDIA 驅動,Secure Boot 可能需要關閉(避免驅動簽章問題)

接著便可順利進入到 Windows 安裝,照著互動 UI 安裝即可,設定完後(順利進入桌面),可拔掉開機的 USB,並重啟電腦測試是否能正確載入。

唯一要注意的地方是 開機硬碟(系統碟),盡量先確認硬碟是空的(我實作時是完全空的),若有殘餘檔案,建議可先刪除,透過磁碟管理或 diskmgmt.msc,若權限不足也可透過 cmd 刪除。

成功: 到這裡已完成 Window OS 的安裝

磁碟管理

這一步的目的是避免 Ubuntu 安裝錯誤或設定錯誤,要先清空將要安裝 Ubuntu 的硬碟資料 [2]

磁碟管理的 UI 介面可從工具列直接開啟(操作略過),以下直接記錄使用 cmd 透過 diskpart 刪除分割區的流程:

注意:操作具有風險,務必確認磁碟與分割區編號,避免誤刪資料

開啟 cmd(系統管理員權限)後輸入:

1
2
3
4
5
6
diskpart                    # 啟動 Windows 內建磁碟管理工具 DiskPart,進入後提示符為 DISKPART>
list disk # 列出所有實體磁碟(含數字編號)
select disk <number> # 選擇要操作的磁碟,務必確認正確
list partition # 列出該磁碟所有分割區
select partition <num> # 選擇要刪除的分割區
delete partition override # 強制刪除分割區(永久刪除資料)

若要整顆磁碟完全清空,也可以使用:

1
clean

clean 會移除整顆磁碟的分割表(GPT/MBR),等同於回到未分割狀態。

Notes
  • 開機流程大致如下:
    1. 開機
    2. 主機板載入 UEFI 韌體
    3. UEFI 讀取 EFI System Partition(ESP)
    4. 執行 bootloader(Windows Boot Manager 或 GRUB)
    5. 由 bootloader 載入作業系統核心
    6. 作業系統啟動

常見名詞:

BIOS / UEFI = 主機板開機韌體(開機時最先執行的程式)

MBR / GPT = 磁碟分割表格式(磁碟如何被切割與管理)

NTFS / ext4 = 檔案系統(作業系統如何儲存檔案)

Secure Boot = UEFI 的安全驗證機制(驗證開機程式是否有數位簽章)


Secure Boot 會檢查 bootloader 與 kernel module 是否有合法簽章。

可能影響:

NVIDIA 驅動安裝

自編 kernel module

某些 Linux 發行版


實作灌 Ubuntu 時常常進不去桌面(黑畫面),目前判斷是因為顯卡驅動載入失敗,kernel 無法載入 NV 顯卡驅動 → 解法:關閉 Secure Boot(BIOS 不一定有選項,可能需借助套件調整)。

※ Ubuntu 安裝 GRUB 時若遇到無法載入 NVIDIA 驅動或黑畫面,通常就是 Secure Boot 阻擋了 kernel module 的簽章
※ 安裝順序建議:先安裝 Windows,再安裝 Ubuntu,由 Ubuntu 自動配置 GRUB

Ubuntu 24.04 LTS 安裝

一樣將製作好的 USB 插入主機後:

  1. 開機按 DelF2 進入 BIOS(ASUS ROG)
  2. 進入 Boot 選項
  3. 將 USB 設為第一開機順位(或直接使用 Boot Override)

此時應會看到前面安裝的 Windows Boot Manager,
這裡要選擇 Ubuntu 開機 USB,而不是 Windows。

GRUB 選單

成功進入後會看到 Ubuntu 的開機選單(嚴格來說這還不是硬碟裡的 GRUB,而是 USB 內的啟動選單),選項包括:

Try or Install Ubuntu

Ubuntu (safe graphics)

Advanced options

Try or Install Ubuntu

首先我選「Try or Install Ubuntu」的結果,這個模式會進入 Live USB 環境(暫時系統):

系統從 USB 執行

尚未安裝到硬碟

可測試硬體是否正常(顯卡 / 網卡 / 音效)


實作時進入桌面後沒有看到完整的安裝 GUI,只看到桌布(疑似顯示或驅動問題),
這時只能用快捷鍵開啟 Terminal 進行操作。

⚠ 若設定完重啟電腦黑屏

極可能原因:

NVIDIA 顯卡驅動未正確載入

Secure Boot 阻擋 unsigned kernel module,導致其未正確載入 kernel


解法分兩種:

  1. 由於有可能是因為 kernel module 沒有合法簽章,被 Secure Boot 拒絕載入,因此需想辦法重新進入桌面,安裝套件或調整 Secure Boot 設定

  2. 更換 Ubuntu 版本(我第一次灌 22.04 失敗,後來改 24.04 才成功)

Ubuntu (safe graphics)

GRUB 中另一個選項是「Ubuntu (safe graphics)」,此模式會使用較保守的顯示設定,避免顯卡驅動初始化問題,且通常可以順利進入安裝 GUI。

安裝時若詢問:

  • 是否下載更新
  • 是否安裝第三方套件(第三方驅動)

建議打勾(需有網路)。

安裝磁碟部分: 我這裡因為有多顆硬碟,因此選擇與 Win10 完全獨立的硬碟安裝 Ubuntu

優點:

互不影響

分割區較單純

出錯率較低


若安裝在同一顆硬碟:

需要共用 EFI 分割區

手動分割較複雜

GRUB 問題機率較高


若沒有網路,可使用手機 USB 網路分享,
否則部分套件(如顯卡驅動、更新)不會自動安裝。

若順利完成安裝:

重啟電腦 → 拔掉 USB → 應會看到硬碟內的 GRUB 選單:

  • Ubuntu
  • Windows Boot Manager

若直接進 Windows,表示開機順序可能被改回 Windows Boot Manager,可回 BIOS 調整。

Notes
NumLock 閃爍:
  • 通常代表 kernel panic 或 kernel 啟動失敗
    可能原因:顯卡驅動問題、分割區錯誤、EFI 設定錯誤
    → 解法:使用 safe graphics 進入,或清除磁碟分割後重灌
若黑屏(完全黑畫面無反應):
  • 可能原因:NVIDIA 驅動未載入、Secure Boot 阻擋 kernel module
    → 解法:使用 safe graphics 或暫時關閉 Secure Boot
若灰屏(與黑屏不同):
  • 系統其實已載入,但顯示管理器或顯卡初始化異常
    可按下:

    1
    Ctrl + Alt + F3

    進入 TTY 終端模式檢查系統狀態。

    也需確認:

    • 是否接了多條螢幕線
    • 是否有額外顯示輸出
    • 是否插著不必要的外接裝置

    Secure Boot & MOK

    若 BIOS 可直接開關 Secure Boot,直接調整即可。
    若沒有,Ubuntu 會使用 MOK(Machine Owner Key)機制。

    安裝驅動後重啟可能出現藍色畫面,類似下圖:

    步驟:

    • 選擇「Enroll MOK」
    • 輸入安裝時設定的密碼
    • 重新開機完成註冊

    DKMS(Dynamic Kernel Module Support)

    在 kernel 更新時重新編譯驅動並掛載到新 kernel。
    常見於 NVIDIA、外接網卡等驅動。
    若更新 kernel 後顯卡失效,可能與 DKMS 失敗有關。

成功: 到這裡應已完成基本的 Ubuntu OS 安裝,並順利載入桌面

NVIDIA 驅動程式檢查

順利進入桌面後,為了能夠正常使用顯卡,需先檢查驅動程式是否已正確安裝。

1️⃣ 先檢查系統建議的驅動版本:

1
ubuntu-drivers devices

系統會列出可用版本,以及「recommended」的版本。

2️⃣ 自動安裝建議版本:會自動安裝系統建議的 NVIDIA 驅動

1
sudo ubuntu-drivers autoinstall

3️⃣ 重啟系統:

1
sudo reboot

4️⃣ 檢查是否成功載入驅動:

1
nvidia-smi

若成功,會顯示 GPU 型號、Driver Version、CUDA Version 以及顯示卡使用狀態表格;若無法執行,可能原因:

驅動未成功安裝

Secure Boot 阻擋 kernel module

DKMS 編譯失敗

版本不相容


可檢查:

1
lsmod | grep nvidia

若有顯示 nvidia 相關模組,代表 kernel module 已載入。

也可查看錯誤訊息:

1
dmesg | grep -i nvidia

目前 host 僅安裝 NVIDIA Driver,未安裝 CUDA Toolkit,因為可能不同的專案版本不同,直接在虛擬環境或是 Docker 容器內安裝即可。

USB 網卡驅動安裝記錄

1️⃣ 查看 USB 裝置:使用 USB 無線網卡後,需確認系統是否正確辨識裝置:

1
lsusb

範例輸出:

1
Bus 001 Device 002: ID 2357:011e TP-Link AC600 wireless Realtek RTL8811AU [Archer T2U Nano]

從輸出可得知晶片型號為:

1
RTL8811AU

2️⃣ 安裝必要套件

1
2
3
4
5
6
7
sudo apt update
sudo apt install build-essential dkms git usbutils -y
sudo apt install -y build-essential dkms git linux-headers-$(uname -r)

git clone https://github.com/morrownr/8821au-20210708.git
cd 8821au-20210708
sudo ./install-driver.sh

系統會問是否需更改設定檔案,若無特殊需求直接跳過即可。

有可能會需要重啟電腦:

1
sudo reboot

測試:

1
ping 8.8.8.8

實作時沒遇到失敗問題,因此依據此次經驗簡單記錄一下可能原因:

若安裝後無法載入模組
  • 可能原因

    • Secure Boot 阻擋 unsigned kernel module
    • DKMS 編譯失敗
  • Secure Boot 開啟,可能需要:

    • 關閉 Secure Boot
    • 或使用 MOK 註冊模組簽章(與前述步驟相同)

Ubuntu的NV CUDA Toolkit與 Docker 環境建置

單機、多使用者環境:

每位使用者可使用 GPU

各專案環境隔離(避免版本衝突)

管理者可控管資源

Host 保持乾淨穩定

Note:

  • 不在 Ubuntu Host 安裝完整 CUDA Toolkit
  • Host 僅安裝 NVIDIA Driver
  • 所有 CUDA / cuDNN / PyTorch 版本都在 Container 內
  • 透過 Docker + NVIDIA Container Toolkit 提供 GPU 支援

優點:

  • 不同專案可使用不同 CUDA 版本
  • 避免污染 Host 環境
  • 版本升級風險較低
  • 容器可快速重建

基本指令

  1. 系統資訊:
1
2
lsb_release -a
uname -a
  1. CPU / RAM
1
2
lscpu
free -h
  1. GPU
1
2
nvidia-smi
nvidia-smi -L
  1. 磁碟
1
df -h

建環境指令

安裝 Docker
1
2
3
sudo apt-get update
sudo apt-get install -y docker.io
sudo systemctl enable --now docker
安裝 NVIDIA Container Toolkit

功能:讓 Docker 容器能「看見」實體顯卡的橋樑

  • 顯卡驅動直接與 Linux Kernel 溝通
  • Docker Container 共用 Host Kernel
  • 容器內的 CUDA 需呼叫 Host 上的驅動 .so 檔案
  • NVIDIA Container Toolkit 負責在容器啟動時掛載這些檔案

顯卡驅動是直接與 Linux Kernel(內核)溝通的,Docker 容器是共用主機內核的,所以驅動必須裝在主機上,容器內的 CUDA 需要呼叫主機上的 .so 驅動檔案。NVIDIA Container Toolkit 就像是一個「搬運工」,在 Container 啟動的一瞬間,把主機的驅動檔案對應進去

Step 1.:設定 NVIDIA 套件來源

1
2
3
4
5
6
7
8
9
10
11
12
# 建立存放金鑰的資料夾
sudo mkdir -p /usr/share/keyrings

# 下載 GPG 金鑰並轉換格式(符合 Ubuntu 24.04 規範)
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg

# 加入 NVIDIA 儲存庫清單
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

sudo apt-get update

Step 2.:設定 NVIDIA 套件金鑰與儲存庫 (讓 Docker 存取 GPU)

1
sudo apt-get install -y nvidia-container-toolkit

Step 3.:設定 Docker 運行環境並重啟

此步驟會自動修改 /etc/docker/daemon.json,告訴 Docker 啟動時要載入 NVIDIA 的 Runtime

1
2
3
# 自動設定並重啟 Docker
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

這會自動修改:

1
/etc/docker/daemon.json

Step 4.:驗證環境隔離測試:

即使主機(Host)沒有安裝任何版本的 CUDA Toolkit,依然可透過不同的 Container 讓不同的 User 使用完全不同的 CUDA 版本

測試 A:模擬 User 1 啟動一個 CUDA 11.8 的環境(可選)


1
docker run --rm -it --gpus all nvidia/cuda:11.8.0-base-ubuntu22.04 nvidia-smi

測試 B:模擬 User 2 啟動一個 CUDA 12.1 的環境 (可選)


1
docker run --rm -it --gpus all nvidia/cuda:12.1.0-base-ubuntu22.04 nvidia-smi

若成功,代表:

Host Driver 正常

Docker 可存取 GPU

可同時支援不同 CUDA 版本 -> Driver 版本需 ≥ Container CUDA 版本


確認安裝無誤 (已驗證實作):

  1. 檢查工具包是否在系統路徑中
1
nvidia-ctk --version
  1. 檢查 Docker 設定檔是否正確寫入
1
cat /etc/docker/daemon.json

輸出內容類似:

1
2
3
4
5
6
7
8
{
"runtimes": {
"nvidia": {
"args": [],
"path": "nvidia-container-runtime"
}
}
}
  1. 從 Docker 內部呼叫外部顯卡
1
sudo docker run --rm --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi

若成功會輸出表格

實作結果:

1
2
3
aivc@aivc602-2:~$ docker --version
Docker version 28.2.2, build 28.2.2-0ubuntu1~24.04.1
aivc@aivc602-2:~$ sudo systemctl enable --now docker

安裝這些對於系統影響非常小,NVIDIA Container Toolkit 本質上只是一個插件和一些函式庫,它不包含顯卡驅動程序,也不會修改原系統的驅動,主要功能只是在 Docker 啟動 Container 時,負責把 Host 的驅動(.so 檔案)掛載(mount)進 Container

移除指令:

1
sudo apt purge nvidia-container-toolkit 

參考來源:NVIDIA Container Toolkit Installation Guide

測試 Docker 容器

佔用顯存的 Python 程式:

1
2
3
4
5
6
7
8
9
10
11
12
import torch
import time

# 檢查 CUDA 是否可用
if torch.cuda.is_available():
device = torch.device("cuda")
# 建立一個佔用約 4GB 顯存的張量 (float32 每單位 4 bytes)
x = torch.randn(1024, 1024, 1024, device=device)
print(f"成功!已在 {torch.cuda.get_device_name(0)} 上分配約 4GB 記憶體")
time.sleep(30) # 可透過 nvidia-smi 來確認
else:
print("找不到 CUDA!")

Docker 運行指令:

1
2
3
4
sudo docker run --rm -it --gpus all \
-v $(pwd):/app -w /app \
pytorch/pytorch:2.4.0-cuda12.4-cudnn9-runtime \
python3 test_gpu.py

(可選)安裝 NVIDIA 官方提供的 Python 監控庫 NVML

1
pip install nvidia-ml-py

NVIDIA Driver 與 CUDA 版本對照表:NVIDIA CUDA Release
PyTorch 官方對照 Pytorch Docker hub

安裝虛擬環境:

Python 虛擬環境工具比較

工具 運作層級 核心用途 優點 缺點
venv 套件層 隔離不同專案的 Python 套件 內建、輕量 無法切換 Python 版本
pyenv 版本層 管理多個 Python 版本 可共存多版本 通常需搭配 venv
Conda 系統層 管理跨語言依賴與 CUDA 相依性管理強 體積大、較重

venv

下載套件:

1
2
sudo apt update
sudo apt install python3-venv python3-full -y

建立虛擬環境(可自行命名):

1
python3 -m venv venv

啟用虛擬環境:

1
source venv/bin/activate

離開虛擬環境:

1
deactivate

venv 只能隔離「套件」,無法切換 Python 版本。

若需要:

  • 不同專案使用不同 Python 版本(例如 3.10 / 3.11 / 3.12)
  • 測試舊版本相容性
  • 避免使用系統內建 Python

則可搭配 pyenv 使用(但以下尚未實作驗證)

pyenv

  • 安裝相依套件:
1
2
3
4
sudo apt update
sudo apt install -y make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev curl llvm \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
  • 安裝pyenv:
1
curl https://pyenv.run | bash
  • 設定環境變數:

將以下內容加入 ~/.bashrc

1
2
3
export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init --path)"
eval "$(pyenv init -)"

重新載入:

1
source ~/.bashrc

確認安裝成功:

1
pyenv --version
  • 基本使用方式:

查看可安裝版本:

1
pyenv install --list

安裝指定版本:

1
pyenv install 3.10.14

刪除 Python 版本:

1
pyenv uninstall 3.10.14

指定 Python 版本:

1
pyenv local 3.10.14

此指令會在指定目錄(當前目錄)下建立 python-version的檔案去修改環境的 PATH,讓 python 指向 pyenv 安裝的版本,可用以下指令驗證:

1
2
which python
python --version

專案虛擬環境建置

pyenv → 控制 Python 版本
venv → 隔離該版本的套件

1
2
3
4
cd my_project
pyenv local 3.10.14
python -m venv venv
source venv/bin/activate

Conda 每個環境通常會複製大量依賴,磁碟空間消耗較高。

Reference