| name | pixi-env |
| description | pixi (conda-forge) でプロジェクト環境を構築・管理するルールと知見。 このような状況の時には必ず参照してください: - pixi.toml / pyproject.toml の [tool.pixi.*] を編集するとき - 新しいパッケージを追加するとき(conda-forge vs PyPI の判断含む) - CUDA/PyTorch 設定、cross-platform 対応 (linux-64/linux-aarch64/osx-arm64) - Docker 統合、conda→pixi 移行、pixi install や solver エラーの対処時
|
| user-invocable | true |
| allowed-tools | Read Grep Bash(pixi *) |
Pixi 環境構築ルール
出典: Notion Pixi Wiki (Advent Calendar 2025) / Pixi FAQ + SyncHuman GH200 対応での実践知見
Note: このスキルはプロジェクト単位の pixi.toml / pyproject.toml による
環境構築を扱う。システムワイドなツール管理 (pixi global / pixi-global.toml)
については nanokit の CLAUDE.md を参照。
基本方針
pixi でプロジェクトの全依存関係を管理する。 conda-forge と PyPI を使い分け、
pixi.toml / pyproject.toml + pixi.lock で再現可能な環境を実現する。
conda-forge と PyPI の使い分け原則
- pure-Python パッケージ: PyPI (
pixi add --pypi)
- 非 Python の依存 (C/C++, CUDA, Rust ツール等): conda-forge (
pixi add)
- 低レイヤの依存は混ぜない: 同じライブラリを conda と PyPI の両方から入れない
理由:
- conda は platform-native バイナリを提供 (ABI 整合性保証)
- PyPI wheel は特定の CUDA/PyTorch ビルドに紐づき、conda 版と混ぜると ABI 不一致で segfault する
- conda-forge は依存ライブラリを共有ライブラリとして管理し、コミュニティで効率よくアップデートする
- PyPI wheel は self-contained (依存を内包) で手軽だが、pip の外側からは使えない
プロジェクト初期化
| 用途 | コマンド | ファイル |
|---|
| Python パッケージにする | pixi init --format pyproject | pyproject.toml ([tool.pixi.*]) |
| それ以外 (C++/Rust/ML 実験) | pixi init | pixi.toml |
Python バージョン指定
conda パッケージとして project-local にインストール:
pixi add python==3.11
src layout (デフォルト)
pixi init --format pyproject は src-layout を生成。
demo = { path = ".", editable = true } により pixi install で editable install される。
.
├── pyproject.toml
└── src
└── demo
└── __init__.py
パッケージ追加の判断フロー
flowchart TD
A[新しいパッケージが必要] --> B{pure-Python?}
B -- Yes --> C["pixi add --pypi <pkg>"]
B -- No / native 依存あり --> D{"pixi search <pkg> --platform linux-64"}
D -- conda-forge にあり --> E["pixi add <pkg>"]
D -- なし --> F["pixi add --pypi <pkg>"]
F --> G{CUDA ソースビルドが必要?}
G -- Yes --> H["git dep + no-build-isolation"]
G -- No --> I[通常の PyPI dep]
E --> J{cross-platform 必要?}
J -- Yes --> K["pixi search <pkg> --platform linux-aarch64 で確認"]
K -- 両方あり --> L["[dependencies] に追加"]
K -- 片方のみ --> M["[target.platform.dependencies] に分離"]
バージョン確認
pixi add <pkg>
pixi search <pkg> --platform linux-64
pixi search <pkg> --platform linux-aarch64
特殊なインストール方法
pixi add で入らない場合、pyproject.toml を直接編集 → pixi install:
[tool.pixi.pypi-dependencies]
sglang = { version = "==0.4.6.post5", extras = ["all"] }
httpx = { git = "https://github.com/encode/httpx.git", rev = "c7c13f1" }
my-module = { path = "./my-module", editable = true }
click = { url = "https://github.com/pallets/click/releases/download/8.1.7/click-8.1.7-py3-none-any.whl" }
Task / Feature / Environment
Task の活用
pixi では shell に入るのではなく task でコマンドを実行するのが基本:
[tasks]
train = { cmd = "python train.py", cwd = "scripts" }
test = "python -m pytest tests/ -v"
lint = "ruff check ."
fmt = "ruff format ."
pixi run train
pixi run train --lr=0.1
pixi run -e gpu train
Feature / Environment
feature を組み合わせて目的別の environment を構成する:
[feature.dev.dependencies]
ruff = "*"
pytest = "*"
[feature.benchmark.dependencies]
pueue = "*"
hyperfine = "*"
[feature.gpu.dependencies]
pytorch = { version = ">=2.5", build = "cuda*" }
[environments]
default = ["dev"]
benchmark = ["dev", "benchmark"]
gpu = ["dev", "gpu"]
- task は定義された feature の environment で自動実行される
pixi install -a で全環境を一括インストール
- benchmark 環境専用の task は
pixi run bench で自動的に benchmark 環境で実行
環境変数
グローバル (activation.env)
[activation.env]
DATA_ROOT = "/path/to/your/data"
タスク固有 (activation.env を上書き)
[tasks.train]
cmd = "python train.py"
env = { CUDA_VISIBLE_DEVICES = "0,1" }
Type 1: シンプルな Python プロジェクト
CUDA や native 拡張が不要な場合。Web アプリ、データ分析、CLI ツール等。
pixi init --format pyproject
pixi add python==3.12
pixi add --pypi fastapi uvicorn sqlalchemy
pixi add ruff pytest --feature dev
[tool.pixi.pypi-dependencies]
myapp = { path = ".", editable = true }
fastapi = ">=0.100"
uvicorn = "*"
sqlalchemy = ">=2.0"
[tool.pixi.feature.dev.dependencies]
ruff = "*"
pytest = "*"
[tool.pixi.environments]
default = ["dev"]
PyPI のみで完結する場合でも pixi を使うメリット:
- lockfile で全依存を固定
- task runner 内蔵
- feature/environment で dev 依存を分離
- 非 Python ツール (ruff 等) も conda で統一管理可能
Type 2: PyTorch / ML プロジェクト (PyPI ベース)
PyTorch を使うが CUDA 拡張のソースビルドは不要な場合。
多くの学習・推論プロジェクトがこれに該当する。
PyPI pytorch (手軽に始める)
PyPI wheel は CUDA runtime を同梱するため、別途 CUDA をインストールする必要がない:
[tool.pixi.pypi-dependencies]
torch = { version = ">=2.5.1", index = "https://download.pytorch.org/whl/cu124" }
torchvision = { version = ">=0.20.1", index = "https://download.pytorch.org/whl/cu124" }
version の検索: https://download.pytorch.org/whl/torch/
制約: PyPI wheel の CUDA runtime は pip の外側の開発用途には使えない (NVIDIA 公式)。
CUDA 拡張のソースビルドが必要な場合は Stage 3 へ。
HuggingFace エコシステム
transformers / diffusers / tokenizers は PyPI で統一する。
[tool.pixi.pypi-dependencies]
transformers = ">=4.36.0,<4.46"
diffusers = "==0.29.1"
huggingface-hub = ">=0.23.0,<1.0"
accelerate = "*"
conda 版 transformers は tokenizers の ABI 不整合を起こす:
module 'decoders' has no attribute 'DecodeStream'
conda-forge パッケージの落とし穴 (transitive dep)
| パッケージ | conda の transitive dep | 問題 | 対策 |
|---|
lpips | opencv | py311 aarch64 ビルドなし | PyPI に残す |
openexr | imath | pytorch と version conflict | PyPI に残す |
rembg | 特定バージョンが conda にない | solver failure | PyPI に残す |
pillow ピン留め問題
conda の torchvision が pillow をピン留めするため、PyPI の pillow と競合。
→ pillow は conda に任せる (PyPI から削除)。
Type 3: CUDA 拡張開発 / conda-forge ベースプロジェクト
CUDA 拡張のソースビルドが必要、またはクロスプラットフォーム対応で
依存関係を厳密に管理したい場合。conda-forge 単 channel に統一すると
依存関係を最も綺麗に管理でき、共有ライブラリが環境内で一貫する。
CUDA の 3 層構造
| 層 | 管理 | 説明 |
|---|
| Driver API | ホスト OS | pixi 管理外。ホストの GPU ドライバを更新 |
| Runtime API | pixi 仮想環境 | ビルド済みアプリ (PyTorch等) の実行に十分 |
| Devtools (nvcc) | pixi 仮想環境 | CUDA 拡張の開発・ビルドに必要 |
pixi 仮想環境は $PROJECT_ROOT/.pixi/envs/ に配置。
$CONDA_PREFIX で CUDA の場所を参照できる。
環境別に異なる CUDA version を共存可能。
conda-forge pytorch + CUDA
[dependencies]
pytorch = { version = ">=2.5.1,<2.6", build = "cuda*" }
torchvision = { version = ">=0.20.1,<0.21", build = "cuda*" }
cuda = ">=12.1,<13"
cuda-version = ">=12.1,<13"
build = "cuda*" を省略すると CPU ビルドが選ばれる可能性がある
cuda-version のみだとヘッダー (cuda_runtime.h) がインストールされない
cuda メタパッケージが nvcc やヘッダーを含む
CUDA バージョンのピン
厳密なピン (cuda-version = "12.1.*") は solver を制約しすぎる。
cuda-version = ">=12.1,<13"
cuda-version = "12.1.*"
nvidia channel vs conda-forge
| 観点 | nvidia channel | conda-forge |
|---|
| CUDA 11 以下 | 推奨 | 非推奨 |
| CUDA 12 以上 | OK | 推奨 |
| cuda-version メタパッケージ | なし | あり |
| C/C++ compiler 付属 | 内部のみ (外から参照不可) | 共有ライブラリ (c/cxx-compiler) |
conda-forge 版は他の conda パッケージから gcc/g++ を参照・再利用できる。
nvidia channel 版の gcc/g++ は外側のパッケージからは見えない。
conda-forge 由来の依存関係を多く抱えるプロジェクトでは、全てを conda-forge 製に揃えた方がトラブルは少ない。
cudatoolkit は deprecated。 CUDA 12 以降は cuda-toolkit に再構成。
タイポ防止のため常に cuda メタパッケージを使う。
CUDA デバッグコマンド
pixi tree cuda
pixi list | grep cuda
pixi run which nvcc
pixi run which gcc
cmake は nvcc の場所から cuda prefix を自動検出する:
cmake_minimum_required(VERSION 3.18)
project(test LANGUAGES CUDA CXX)
PyPI pytorch (代替)
Stage 2 と同様だが、CUDA 拡張ビルド用に conda の cuda パッケージを追加する:
[tool.pixi.pypi-dependencies]
torch = { version = ">=2.5.1", index = "https://download.pytorch.org/whl/cu124" }
torchvision = { version = ">=0.20.1", index = "https://download.pytorch.org/whl/cu124" }
[dependencies]
cuda = ">=12.4,<13"
cuda-version = ">=12.4,<13"
pytorch channel (deprecated)
PyTorch 公式の conda package はメンテされていない。既存コードの移行時のみ:
[workspace]
channels = ["pytorch", "nvidia/label/cuda-11.8.0", "nvidia", "conda-forge"]
pixi add pytorch torchvision torchaudio pytorch-cuda=11.8
PyPI パッケージの no-build-isolation
PEP 517 違反のパッケージ (ビルド時に外部の torch/CUDA を参照するもの) は
no-build-isolation で pixi 環境をビルドに見せる:
[pypi-dependencies]
nvdiffrast = { git = "https://github.com/NVlabs/nvdiffrast.git" }
[pypi-options]
no-build-isolation = ["nvdiffrast"]
submodule のローカルパッケージ
[pypi-options]
no-build-isolation = ["my-submodule"]
[pypi-dependencies]
my-submodule = { path = "./submodules/my-submodule", editable = true }
flash-attn
方式 1: pre-build wheel (手軽)
python, pytorch+cuda の version と整合する third-party wheel を選ぶ:
[tool.pixi.pypi-dependencies]
torch = { version = "==2.4.1", index = "https://download.pytorch.org/whl/cu121" }
flash-attn = { url = "https://github.com/mjun0812/flash-attention-prebuild-wheels/releases/download/v0.3.11/flash_attn-2.8.0+cu121torch2.4-cp312-cp312-linux_x86_64.whl" }
方式 2: no-build-isolation でビルド
pixi add setuptools psutil packaging ninja wheel libxcrypt cuda==12.4.1 cuda-version==12.4
[tool.pixi.pypi-options]
no-build-isolation = ["flash-attn"]
pixi install
pixi add --pypi flash-attn
pixi list | grep cuda で torch が使う cuda と minor version を合わせること。
方式 3: conda-forge (両 platform ビルドあり、ソースビルド不要)
[dependencies]
flash-attn = { version = ">=2.7,<2.8", build = "py311*" }
diff-gaussian-rasterization の CUDA 12.6+ 問題
公式リポは std::uintptr_t / uint32_t が未定義でビルド失敗。
→ ashawkey fork を使う。戻り値が 3 値なので rendered, *_ = rasterizer(...) とする。
Cross-Platform (linux-64 + linux-aarch64 + osx-arm64)
platforms 宣言
[workspace]
platforms = ["linux-64", "linux-aarch64", "osx-arm64"]
macOS 固有の注意点
- CUDA は macOS に存在しない → GPU feature は
platforms = ["linux-64", "linux-aarch64"] で制限する
- macOS で MPS (Metal) を使う場合、PyTorch の CPU ビルドで十分 (MPS は CPU wheel に含まれる)
マルチプラットフォーム対応のヒューリスティクス
- まず
[target.linux-64.pypi-dependencies] に pypi package を全部移して pixi install
[pypi-dependencies] (共通) にちょっとずつ移して都度 pixi install
- エラーが出たものだけ platform 別に振り分ける
[tool.pixi.pypi-dependencies]
[tool.pixi.target.linux-64.pypi-dependencies]
[tool.pixi.target.linux-aarch64.pypi-dependencies]
platform 別 dependency
[target.linux-64.dependencies]
kaolin = ">=0.17,<0.18"
xformers = ">=0.0.28"
注意: 同じ [target.linux-64.dependencies] セクションは TOML で 1 回のみ。
feature の platform 制限
[feature.gpu-full]
platforms = ["linux-64"]
Channel Priority
Channel priority は仕様上動的に変更できない。特定 channel から入れたい場合:
cuda = { version = "==12.1.1", channel = "conda-forge" }
[feature.gpu]
channels = ["nvidia", "conda-forge"]
Dependency Overrides
サバンナのパッケージは依存バージョンの上限指定が大体間違っている。
PR を送らずにバージョン制約を上書きできる:
[tool.pixi.pypi-options.dependency-overrides]
numpy = ">=2.0.0"
すべての依存関係のバージョン制約を無視するため慎重に使うこと。
prerelease パッケージ
依存が dev 版を要求する場合:
[tool.pixi.pypi-options]
prerelease-mode = "allow"
conda → pixi 移行
Case 別アプローチ
| Case | 状況 | 手法 |
|---|
| 1 | 完璧な environment.yml がある | pixi init --import environment.yml && pixi install |
| 2 | 不完全な environment.yml | defaults 削除 → submodule 分離 → Divide-and-Conquer |
| 3 | 依存ファイルが一切ない | pixi init --pyproject で手動構築 |
Divide-and-Conquer (Case 2)
defaults channel を削除 (有償化問題、pixi ではデフォルト無効)
- submodule の依存を一旦消す
- 本体の依存を先に解決 → lockfile 生成
- submodule を
[pypi-dependencies] + no-build-isolation で追加
pixi install で一括インストール
defaults channel について
| conda distribution | default channel | license |
|---|
| Anaconda / miniconda | defaults (repo.anaconda.com) | 有償 |
| miniforge / pixi | conda-forge | 無償 |
environment.yml に defaults が残っていたら削除する。
CUDA 3 重インストール防止
conda cudatoolkit (deprecated)、nvidia channel の cuda-toolkit、PyPI wheel の CUDA runtime が
3 重に入ると競合する。CUDA は 1 つだけ入れる (conda-forge の cuda メタパッケージ推奨)。
Docker 統合
基本パターン
FROM ghcr.io/prefix-dev/pixi:0.61.0
WORKDIR /workspace
COPY pixi.toml pixi.lock ./
RUN pixi install -a
pixi 公式の base image を使えば、プロジェクト毎に Dockerfile をチクチク書く必要がない。
pixi install -a するテンプレを使い回して一瞬で Docker 化できる。
multi-stage build (image サイズ削減)
ARG BASE_IMAGE=ghcr.io/prefix-dev/pixi:0.61.0
FROM ${BASE_IMAGE} as build
WORKDIR /workspace
COPY pixi.toml pixi.lock ./
RUN pixi install -a
FROM ${BASE_IMAGE}
COPY --from=build /workspace/.pixi/envs/default /workspace/.pixi/envs/default
.pixi ボリューム分離 (重要)
ローカルの .pixi と container の .pixi が共有されると必ず壊れる。
volumes:
- $PWD:/workspace
- pixi_env:/workspace/.pixi
volumes:
pixi_env: {}
pixi の限界
Linux kernel や glibc は仮想環境で管理できない → system-requirements に記載:
[system-requirements]
linux = "4.18"
libc = { family = "glibc", version = "2.28" }
cuda = "12"
管理階層
docker で管理可能な依存関係
└── pixi で管理可能な依存関係
└── cuda (libcudart.so 等)
└── glibc
host で管理する依存関係
└── nvidia driver (nvidia.ko, libnvidia.so)
└── Linux kernel
pixi shell / pip install の注意
pixi shell
pixi shell -e gpu-full
pixi では task での実行が基本。デバッグ以外で shell に入らない。
pip install の禁止
pixi shell & pip install は pixi.lock に記録されない。やむを得ない場合:
pixi add pip で project-local pip を入れる
pixi run python -m pip install ... で実行
- pixi task 化して再現可能にする
環境テスト
新しい環境構築後は tests/test_environment.py で全パッケージの import を検証:
pixi run python -m pytest tests/test_environment.py -v
テストが検証する項目:
- PyTorch/torchvision が期待する由来 (conda-forge or PyPI) であること
- flash-attn/xformers/kaolin が正しい由来であること (ABI 整合性)
- HuggingFace tokenizers ABI が正常 (AutoencoderKL import)
- CUDA headers (cuda_runtime.h) と nvcc が存在すること (Stage 3)
- 全 native extension が importable であること
CLAUDE.md への環境要件記録
pixi install が成功したら、対象プロジェクトの CLAUDE.md に環境メモを残す。
バージョンや依存一覧など toml / lock を読めば分かる情報は書かない。
記録タイミング
pixi init + 初回 pixi install 完了後
- conda vs PyPI の判断や platform 分離など設計判断を行った後
記録する内容
- 設定ファイルへのポインタ: どの toml を見ればよいか (
pixi.toml or pyproject.toml [tool.pixi.*])
- 非自明な設計判断とその理由: toml を読むだけでは分からない「なぜ」
- conda vs PyPI の選択理由 (例: tokenizers ABI 不整合回避で PyPI 統一)
- platform 分離の理由 (例: kaolin に aarch64 ビルドなし)
- no-build-isolation の背景 (例: ビルド時に環境の torch/CUDA を参照)
- dependency-overrides の経緯 (例: 上流の numpy 上限が間違い)
- セットアップ手順:
pixi install 以外に必要なステップがあれば
記録フォーマット例
## Pixi environment
設定: `pyproject.toml` (`[tool.pixi.*]`)
設計判断:
- `transformers` / `tokenizers` は PyPI 統一 — conda-forge 版は tokenizers の Rust ABI 不整合を起こす
- `flash-attn` は pre-build wheel URL 指定 — ソースビルドに 30 分以上かかるため
- `kaolin` は `[target.linux-64.dependencies]` に分離 — aarch64 ビルドが存在しない
```bash
pixi install -a
```
記録ルール
- コンパクトに: 10–15 行以内を目安
- 理由を残す: 「何を」ではなく「なぜそうしたか」を書く
- 既存の
## Pixi environment セクションがあれば上書き、なければ末尾に追加
- CLAUDE.md の他のセクションを壊さない
環境のリセット
pixi clean cache
pixi clean
rm pixi.lock
pixi install -a
ストレージ逼迫時は dua i や diskonaut で肥大化した環境を特定:
pixi global install dua-cli diskonaut
トラブルシューティング
| 症状 | 原因 | 対策 |
|---|
cuda_runtime.h: No such file | cuda メタパッケージ未インストール | cuda = ">=12.1,<13" を追加 |
undefined symbol: _ZN3c10... | PyPI wheel と conda pytorch の ABI 不一致 | 出所を統一 (conda or PyPI) |
module 'decoders' has no attribute | conda transformers + tokenizers 不整合 | PyPI に戻す |
No candidates found for ... aarch64 | パッケージに aarch64 ビルドなし | [target.linux-64.dependencies] に移動 |
| solver が CPU pytorch を選ぶ | build = "cuda*" 未指定 | build constraint 追加 |
| pillow version conflict | conda torchvision が pillow をピン | PyPI から pillow を削除 |
std::uintptr_t undefined | CUDA 12.6+ と古い C++ コード | ashawkey fork 使用 |
too many values to unpack | ashawkey fork の戻り値が 3 値 | rendered, *_ = ... |
.pixi が Docker で壊れる | host/container で共有 | 空ボリュームで分離 |
cudatoolkit が見つからない | deprecated パッケージ名 | cuda メタパッケージを使う |
defaults channel エラー | environment.yml に残存 | 削除 (pixi では無効) |
| CUDA が 3 重にインストール | cudatoolkit + cuda-toolkit + wheel | conda cuda 1 つに統一 |
| GPU driver と CUDA 非互換 | ホスト driver が古い | ホスト driver を更新 |
| prerelease エラー | 依存が dev 版を要求 | prerelease-mode = "allow" |
numpy<2 で conflict | 上流の上限指定が間違い | dependency-overrides で上書き |
| channel priority を変えたい | 仕様上動的変更不可 | パッケージ単位 or environment 単位で指定 |
| lockfile と toml の不整合 | 手動編集後に lock 未更新 | pixi clean && rm pixi.lock && pixi install -a |
pixi install が終わらない | solver の探索空間が広い | version range を狭める、build = "..." で絞る |
| ストレージ逼迫 | .pixi が肥大化 | dua i で特定、pixi clean |
JIT コンパイル系ライブラリと conda CUDA (aarch64)
spconv / cumm 等の pccm ベースのライブラリは、初回 import 時に CUDA カーネルを
JIT コンパイルする。conda/pixi 管理の CUDA 環境では追加対応が必要。
conda CUDA と /usr/local/cuda の乖離
JIT 系ライブラリは /usr/local/cuda/ をハードコードしている。
conda では CUDA が $CONDA_PREFIX 配下にインストールされるため、JIT がヘッダーやライブラリを見つけられない。
sudo cp -rsf $CONDA_PREFIX/targets/sbsa-linux/include/* /usr/local/cuda/include/
for f in "$CONDA_PREFIX"/lib/libcuda*.so* "$CONDA_PREFIX"/lib/libnvrtc*.so*; do
sudo ln -sf "$f" "/usr/local/cuda/lib64/$(basename "$f")"
done
sudo cp -rsf $CONDA_PREFIX/targets/x86_64-linux/include/* /usr/local/cuda/include/
editable install が必須
cumm は JIT コンパイル時に自身の C++ ヘッダー (include/tensorview/) を参照する。
通常の wheel install ではヘッダーが含まれないため、git clone + editable install が必要。
pixi add pip
git clone --recursive https://github.com/FindDefinition/cumm.git /tmp/cumm-src
pixi run python -m pip install --no-build-isolation -e /tmp/cumm-src
git clone --recursive https://github.com/traveller59/spconv.git /tmp/spconv-src
pixi run python -m pip install --no-build-isolation --no-deps -e /tmp/spconv-src
pixi の宣言的設定 ([pypi-dependencies]) では editable git install + --no-deps を
表現できないため、pixi task 化して再現可能にする。
pixi 環境内の pip 解決
pixi タスク内の bare pip はシステムの /usr/bin/pip に解決される場合がある。
pixi add pip で環境に pip を入れた上で python -m pip を使う。