【修行】1CPU・容量制限VMでTensorFlow 2.4.0をソースビルドして.whl生成するまでの全記録
📌 はじめに
- よく昔の環境で作られたコードをcloneしたくなると思います。pipでは落とせないバージョンのライブラリが必要になりがちですよね。今回はそんな話です。
- 環境制限がある中で TensorFlow をソースからビルドする必要がありました。
- 特に以下のような条件でのチャレンジでした:
- 仮想マシン(VM)
- 1CPU・低メモリ(5GB)
-
/
パーティションの容量が約36GB、空きは約8GB前後 - TensorFlow 2.4.0 + FMA命令無効化でカスタムビルド
🛠 ビルドの目的と背景
- 開発対象のCPUがFMA命令に未対応 → pip版TensorFlowだと起動時に
Illegal instruction
が出る - 公式ビルドでは
-mfma
などの最適化オプションが有効になっている - そのため、自分でFMA命令の最適化を無効化したTensorFlowをビルドする必要があった
- GPU使わない方針です。
💻 環境構成
項目 | 内容 |
---|---|
OS | Ubuntu 24.04 (VM上) |
CPU | 1 core (VirtualBox) |
メモリ | 5GB |
ディスク容量 |
/ に36GB(うち8GB空き) + /mnt/VmShare に222GB(共用マウント) |
Python | Miniconda環境でPython 3.8(score_sde_env ) |
Bazel | v3.7.2(TensorFlow 2.4.0に合わせた) |
ビルドの流れ(概要)
- TensorFlow公式リポジトリ(r2.4)をclone
-
./configure
でFMAやXLAの有無などを指定 - Bazelによるビルドを開始
- キャッシュ・メモリ・tmpの最適化
- Python依存 (
keras_preprocessing
) エラー対応 -
.whl
ファイルを生成
ポイント解説
1. FMA命令の無効化
-
CC_OPT_FLAGS="-march=native -Wno-sign-compare"
のような設定を./configure
時に与える - または
--copt=-mfma
を入れないよう注意
2. /
容量制限に対する対策
-
~/.cache/bazel
が肥大化するので/mnt/VmShare
に逃がす方法を検討 -
TMPDIR
やTEST_TMPDIR
を/mnt/VmShare/tmp
に指定し一時ファイルを回避
export TMPDIR=/mnt/VmShare/tmp
export TEST_TMPDIR=/mnt/VmShare/tmp
3. Python依存の問題
ModuleNotFoundError: No module named 'keras_preprocessing'
→ pip install keras_preprocessing
で解決
4. Bazel再開とキャッシュの扱い
- 再起動後も
~/.cache/bazel
が残っていれば再開可能 -
bazel build //tensorflow/tools/pip_package:build_pip_package
を何度も繰り返す
5. コンパイラのバージョン、pythonのバージョン
- bazelでビルド中に呼ばれるコンパイラ(gcc, g++)、pythonのバージョンを適切にしましょう。
- gcc: gcc-9
- g++: g++-9
- python: 3.8.20
- pipも20.3.4ぐらいまで落としておいた方が良い(意外と重要らしい)
5. 出力先のパーミッション問題
mkdir: cannot create directory ‘/mnt/VmShare’: Permission denied
→ 一旦 ~/tf_pkg
に出力し、あとから共有領域へ移動
./bazel-bin/tensorflow/tools/pip_package/build_pip_package ~/tf_pkg
🎉 ビルド成功!
ls ~/tf_pkg/
tensorflow-2.4.0-cp38-cp38-linux_x86_64.whl
→ .whl
ができたら、あとはお好きな環境に pip install
するだけ!
学んだこと
- ビルドシステムは「ファイルの依存だけでなく、ツールや中間生成物の構造も扱っている」
- Bazelの内部構造(外部リポジトリ取得・キャッシュ・DAGベースの依存評価)
- リソース制約下での戦略的な判断(何を捨てて、何を通すか)
- 反省として、最初からオブジェクトファイルの出力先を以下に指定しておけば楽ができた。
export TEST_TMPDIR=/mnt/VmShare/tmp
- bazelはSIGINTで途中で止めても、再開時途中からビルドしてくれます。有効活用できます。
おまけ
- TensorFlow公式ビルド手順:https://www.tensorflow.org/install/source
- Bazelの公式ガイド:https://bazel.build/
- FMA・AVX命令とは?:https://en.wikipedia.org/wiki/FMA_instruction_set
最後に
今回のやり方では/
パーティションに30GBほど余裕があると嬉しいですね。
一回のビルドで50時間程かかりました。
この経験が、誰かの「ビルドこわい…」を「やってみようかな」に変えるきっかけになれば幸いです。
TensorFlowのビルドは、C++だけでなくPython・Protobuf・生成スクリプト・依存管理ツールが密接に絡み合っています。
Bazelはその複雑な構造を、Skyframeによるグラフ評価エンジンで一元管理しているそうです。
今回の経験で、それが“使うだけのツール”から“構造を設計する技術”に見えてきました。
References
- TensorFlow公式:ソースビルドガイド
- Bazel公式:Concepts ← DAGやSkyframeの考え方が重要
- Bazel Deep Dive Slides ← 評価エンジンのしくみを知りたい方向け
- Understanding Bazel’s Caching Mechanism