FedoraでBlackwell向けllama.cppをビルドする

Fedora 44 環境で NVIDIA Blackwell 向けに CUDA 対応の llama.cpp を ビルド・インストールする手順をまとめました。

BlackwellのGPUを買ったので、それを使える llama.cpp を Fedora 44(本記事執筆時)でビルドする手順を記録しておきます。 なお、それ以前に Radeon 向けに llama.cpp をビルドできる環境だったので、 基本的な C/C++ コンパイラやツールチェイン、それに cmake などはインストール済みなので、そのあたりに説明抜けがあるかも。

基本的な情報は公式の CUDA-FEDORA.md を参考にしてください。

Fedoraで Blackwell 向け、つまりCUDAを使った llama.cpp のビルドは次のようなステップで進行します。

  1. 標準レポジトリから必要なパッケージをインストールする
  2. RPMFusion (プロプライエタリなソフトウェアを含むレポジトリ) を登録し、ドライバをインストールする
  3. NVIDIAのレポジトリを登録し、CUDA Toolkit をインストールする
  4. llama.cpp をビルドする

では各ステップを詳しく見ていきましょう。

標準レポジトリから必要なパッケージをインストールする

インストール済みパッケージをディストリビューションの状態に合わせます。 更新したり場合によってはダウングレードも。

sudo dnf distro-sync

必要なパッケージをインストールする。 ninja-build は並列ビルドのために、好んで使ってます。

sudo dnf install @c-development @development-tools cmake ninja-build

RPM Fusion を登録し、ドライバをインストールする

NVIDIA & CUDA のドライバをインストールするために、RPM Fusionを登録します。 RPM Fusion は Fedora Project が配布しない(できない?)バイナリ RPM を提供してくれています。

sudo dnf install \
  https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm \
  https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm

そしてドライバをインストールします。 akmod-nvidia はカーネルモジュールのビルドが行われるので、ちょっと時間がかかるかも?

sudo dnf install xorg-x11-drv-nvidia-cuda akmod-nvidia

で、ドライバを有効にするために、いったんこの時点でリブートすると良いでしょう。

sudo reboot

NVIDIAのレポジトリを登録し、CUDA Toolkit をインストールする

NVIDIA のレポジトリを登録します。

sudo dnf config-manager addrepo \
  --from-repofile=https://developer.download.nvidia.com/compute/cuda/repos/fedora$(rpm -E %fedora)/x86_64/cuda-fedora$(rpm -E %fedora).repo

参考 - Fedora44 向けのレポジトリ: https://developer.download.nvidia.com/compute/cuda/repos/fedora44/x86_64/

CUDA Toolkit をインストールします。

sudo dnf install cuda-toolkit

またインストールした CUDA に環境変数 PATH を通しておきましょう。

export PATH=/usr/local/cuda/bin:$PATH

さぁこれでビルドする準備が整いました。

llama.cpp をビルドする

llama.cppのビルドは以下のステップで進めます。

  1. ソースをクローン
  2. ビルド用のディレクトリをセットアップ
  3. ビルド & インストール

ソースをクローン

普通に git でクローンしてください。

git clone https://github.com/ggerganov/llama.cpp.git

履歴なんかいらないよ、っていうのであれば --depth 1 オプションを付けても良いですね。

git clone --depth 1 https://github.com/ggerganov/llama.cpp.git

そして clone したディレクトリに移動しておきます。

cd llama.cpp

ビルド用のディレクトリをセットアップ

ここが少し大変です。 実行するのはこんなスクリプトです。 ビルド用のディレクトリの名前は build-nvidia で、 インストール先は /opt/llama.cpp に設定しています。

BUILD="build-nvidia"
PREFIX="/opt/llama.cpp"

cmake -B "$BUILD" \
  -DCMAKE_C_COMPILER_LAUNCHER=ccache \
  -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
  -DCMAKE_CUDA_FLAGS="-allow-unsupported-compiler" \
  -DCMAKE_INSTALL_PREFIX="${PREFIX}" \
  -DCMAKE_INSTALL_RPATH="${PREFIX}/lib64" \
  -DGGML_CUDA=ON \
  -DGGML_NATIVE=ON \
  -DGGML_BUILD_TESTS=OFF \
  -DLLAMA_BUILD_TESTS=OFF \
  -DCMAKE_BUILD_TYPE=Release \
  -G Ninja

cmake に渡しているオプションの意味は以下の通りです。

# ccache を使って2回目以降のビルドを速くする
-DCMAKE_C_COMPILER_LAUNCHER=ccache
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache

# デフォルトのgcc 16を使うために必要。CUDAはgcc 15を使ってビルドされており、
# 異なるコンパイラを弾くのでこの設定でそれを無効化している
-DCMAKE_CUDA_FLAGS="-allow-unsupported-compiler"

# インストール先を `/opt/llama.cpp` にするために必要な設定
-DCMAKE_INSTALL_PREFIX="${PREFIX}"
-DCMAKE_INSTALL_RPATH="${PREFIX}/lib64"

# CUDAを使うための設定
-DGGML_CUDA=ON

# ビルドしているマシンに最適化する。これでBlackwell対応の楽ができる
-DGGML_NATIVE=ON

# テスト用のプログラムをビルドしないようにする。ちょっとだけビルドが速くなる
-DGGML_BUILD_TESTS=OFF
-DLLAMA_BUILD_TESTS=OFF

# リリース用のバイナリを作る。余計なものがなくなり実行速度が速くなる
-DCMAKE_BUILD_TYPE=Release

# 並行動作に定評のある ninja バックエンドを用いる
-G Ninja

ビルド & インストール

以下のようにしてビルド。 もしかしたら --config Release は、前のステップで -DCMAKE_BUILD_TYPE=Release を指定したので、不要かも?

cmake --build build-nvidia --config Release

CUDAのコンパイルで並列度合いが高すぎて死ぬ場合がありますが、 失敗しても繰り返せばいつかは通ります。

ビルドが成功したら ./build-nvidia/build/binllama-server などが作られます。

そしてついにインストール!

sudo cmake --install build-nvidia

お疲れさまでした。あとは /opt/llama.cpp/bin を環境変数 PATH に追加するなり、 直接実行したりできます。

おまけ

更新する場合

llama.cpp を更新してビルドする場合は以下の手順になります。

cd llama.cpp
git pull -p
cmake --build build-nvidia --config Release
sudo cmake --install build-nvidia

簡単ですね。

私用のスクリプト

ビルド以降のステップには、私はこんなスクリプト (upgrade-llama-nvidia) を作って対応しています。 llama.cpp は更新が速いので、1日の内に何度も更新がありますから、 ちょっと最先端をつまみ食いするのに使ってます。

#!/usr/bin/env bash

set -euo pipefail

SRCDIR="/home/koron/work/llama.cpp"
BUILD="build-nvidia"
PREFIX="/opt/llama.cpp"

(
  cd "${SRCDIR}"

  export PATH=/usr/local/cuda/bin:$PATH

  git pull -p

  cmake -B "$BUILD" \
    -DCMAKE_C_COMPILER_LAUNCHER=ccache \
    -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
    -DCMAKE_CUDA_FLAGS="-allow-unsupported-compiler" \
    -DCMAKE_INSTALL_PREFIX="${PREFIX}" \
    -DCMAKE_INSTALL_RPATH="${PREFIX}/lib64" \
    -DGGML_CUDA=ON \
    -DGGML_NATIVE=ON \
    -DGGML_BUILD_TESTS=OFF \
    -DLLAMA_BUILD_TESTS=OFF \
    -DCMAKE_BUILD_TYPE=Release \
    -G Ninja

  cmake --build "$BUILD" --config Release

  sudo cmake --install "$BUILD"
)

環境変数 PATH

本文中で言及した環境変数 PATH は、そのセッションを閉じると失われてしまいます。

export PATH=/usr/local/cuda/bin:$PATH
export PATH=/opt/llama.cpp/bin:$PATH

これらは必要に応じて、 ~/.bashrc/etc/profile.d/ に書き足して、 永続化しておくと良いでしょう。