はじめに
macOS(Apple Silicon)で、Anaconda を完全に削除し uv ベースの venv 環境に移行しました。用途は Kaggle 形式のデータサイエンス/DL コンペで、LightGBM XGBoost CatBoost PyTorch (MPS) を組み合わせて使っています。
移行作業中に「torch の MPS 学習に成功した直後に LightGBM を実行するとセグフォルトする」という厄介な問題にぶつかったので、原因調査から解決までの流れと、Anaconda 削除の手順、そして今後同種のトラブルに遭遇したときのための汎用的な切り分け方をまとめます。
先に結論だけ知りたい方向け: 原因は「torch と scikit-learn が同梱する libomp.dylib」と「Homebrew の libomp.dylib」が別ファイルとしてプロセス内に二重ロードされ、OpenMP の初期化が衝突していたことでした。
最終的な環境構成
- venv 本体:
uv venvで作成(Python 3.13系) - パッケージ管理:
uv pip(素のpipコマンドではない。venv にpip自体が同梱されていないため) - Homebrew:
brew install uv open-mpi libomp cairo android-platform-tools
新規ターミナルで torch(MPS) → LightGBM → XGBoost → CatBoost の全動作を確認できたところで移行完了としています。
ハマったポイントと解決策
1. LightGBM 実行時のセグフォルト(OMP: Error #179)
症状
=== LightGBM ===
OMP: Error #179: Function pthread_mutex_init failed:
OMP: System error #22: Invalid argument
zsh: segmentation fault python3 quick_env_check.py
torch の MPS 学習が成功した直後に LightGBM を実行するとクラッシュします。一方で、LightGBM 単体(torch を import しない状態)を実行した場合には発生しません。この「単体では起きないが、他のライブラリの後だと起きる」という再現条件が、原因調査の大きな手がかりになりました。
根本原因
torch と scikit-learn は、それぞれ自分専用の libomp.dylib を wheel に同梱しています(pip/uv でインストールした場合、パッケージ内に埋め込まれています)。これが Homebrew の libomp.dylib(LightGBM/XGBoost/CatBoost が参照するもの)と物理的に別ファイルであるため、同一プロセス内に異なる OpenMP ランタイムが複数ロードされ、初期化処理が衝突します。これは macOS の libomp まわりでよく知られている問題で、LightGBM の Issue でも報告されています(microsoft/LightGBM#4229, #4897)。
確認方法
find <venvのsite-packages> -iname "libomp*.dylib" -exec ls -la {} \;
shasum -a 256 <torch側libomp> <Homebrew側libomp>
サイズやハッシュ値が異なっていれば、別ファイルとして二重にロードされていることが確定します。
解決策
torch / scikit-learn が同梱する libomp を削除し、Homebrew の libomp への symlink に置き換えることで「プロセス内で使われる libomp を1つに統一」します。
# torch
TORCH_LIBOMP=<venv>/lib/python3.13/site-packages/torch/lib/libomp.dylib
HOMEBREW_LIBOMP=/opt/homebrew/opt/libomp/lib/libomp.dylib
cp "$TORCH_LIBOMP" "${TORCH_LIBOMP}.orig_backup"
rm "$TORCH_LIBOMP"
ln -s "$HOMEBREW_LIBOMP" "$TORCH_LIBOMP"
# scikit-learn も同様の手順で対応
# パスは <venv>/lib/python3.13/site-packages/sklearn/.dylibs/libomp.dylib
⚠️ 再発条件に注意
torch や scikit-learn を uv pip install -U などでアップデートすると、パッケージが再インストールされる際に symlink が通常ファイルへ巻き戻されます。LightGBM が再びクラッシュするようになったら、まず symlink が生きているかを確認してください。
ls -la <venv>/lib/python3.13/site-packages/torch/lib/libomp.dylib
ls -la <venv>/lib/python3.13/site-packages/sklearn/.dylibs/libomp.dylib
lrwxr-xr-x(symlink)ではなく通常ファイル(-rwxr-xr-x)に戻っていたら、上記の symlink 置換を再実行します。
2. venv に pip が同梱されていない
uv venv で作成した環境には、デフォルトでは pip が含まれていません。ここで素の pip install ... を実行すると、PATH 上の別の場所(移行前であれば Anaconda 側など)に誤ってインストールされてしまうことがあるため注意が必要です。
必ず uv pip install ... を使うこと。 python3 -m pip も、そもそも pip モジュール自体が存在しないため使えません。
3. (base) プロンプトの残留は無害だが、原因は別途切り分ける
conda deactivate した後もシェルプロンプトに (base) が残ることがありますが、これ自体は conda init が仕込んだプロンプト書き換え関数の見た目上の残留であり、単独では無害です。ただし CONDA_SHLVL や PATH の状態は別問題として必ず確認しましょう。
echo "CONDA_SHLVL: $CONDA_SHLVL"
echo "DYLD_LIBRARY_PATH: $DYLD_LIBRARY_PATH"
which -a python3 pip
CONDA_SHLVL=0 であれば、プロンプト表示だけの問題で実害はないと判断できます。
4. Anaconda 本体削除時の Permission denied
rm -rf /opt/anaconda3 で中身自体は削除できますが、ディレクトリ本体(/opt 直下、root:wheel 所有)の削除には管理者権限が必要な場合があります。
sudo rm -rf /opt/anaconda3
実行時にログインパスワードの入力を求められますが(画面には表示されません)、これは Anaconda の認証情報とは無関係な、macOS の sudo 認証です。
Anaconda 削除の手順まとめ
各ステップでバックアップ・確認を挟みながら進めました。
-
.zshrcのバックアップを取るcp ~/.zshrc ~/.zshrc.backup_<timestamp> -
conda の base 環境設定を退避する
conda run -n base anaconda-clean --yes設定は
~/.anaconda_backup/<timestamp>/に退避されます。 -
削除前チェック
-
CONDA_SHLVL=0であること - カスタム環境が残っていないこと
- バックアップファイル(
backup_base_list.txt等)が存在すること
-
-
Anaconda 本体を削除する
sudo rm -rf /opt/anaconda3 -
.zshrcから conda 初期化ブロックを削除するsed -i '' '/# >>> conda initialize >>>/,/# <<< conda initialize <<</d' ~/.zshrc -
新しいターミナルタブを開いて最終確認する
同じターミナルセッションでは古い環境変数が残ったままになるため、必ず新規タブで確認します。
-
which conda→ not found であること -
which mpicc→/opt/homebrew/bin/mpiccが見えること(PATH の恒久化作業は不要で、Anaconda を削除するだけで自動的に解消されました) - venv 内で
torch → LightGBM → XGBoost → CatBoostが全て問題なく完走すること
-
トラブルシューティングの型(他の環境構築でも使える汎用パターン)
今回の調査を通じて、ライブラリ絡みの環境トラブルに共通して使える切り分け手順が見えてきたので、まとめておきます。
- 切り分け: 単体で import しただけで再現するのか、実際に実行(学習・計算など)したときのみ再現するのかを先に区別する
-
環境変数の残留確認:
env | grep -iE "対象キーワード"で怪しい環境変数が残っていないか確認する - 新規シェルでの再現確認: 現在のシェルの状態に依存していないか、必ず新しいターミナルを開いて再現するか確認する
-
バイナリの依存関係を直接見る:
otool -L(macOS)で共有ライブラリの実際のリンク先を確認する -
同名ファイルの物理的な同一性を疑う: 同じライブラリ名でも、パッケージごとに複数バージョン・複数コピーが存在しうる。
shasumやファイルサイズで比較して同一性を確認する -
パッケージ管理コマンドが正しい環境をターゲットにしているか確認する:
which -a pip等で複数の候補が見つかる場合は要注意。今回のuv環境のように、専用のパッケージマネージャコマンド(uv pip)を使う必要があるケースもある
まとめ
- Anaconda から
uv+venvへの移行自体は、本体削除とシェル設定のクリーンアップだけであれば難しくありません。 - ただし、
torch/scikit-learnが同梱するlibomp.dylibと、LightGBM/XGBoost/CatBoost が参照する Homebrew のlibomp.dylibが衝突し、セグフォルトを起こすことがあります。これは Homebrew 経由で GBM 系ライブラリを使う macOS 環境ではハマりやすいポイントなので、同様の症状に遭遇した方の参考になれば幸いです。 - ライブラリのアップデートで symlink が巻き戻り再発することがあるため、CI やセットアップスクリプトに組み込む場合はチェック処理を入れておくと安心です。