# CPU

CPU は、アクセラレータなしでデバイス文字列 `cpu` を使用して Transformers モデルを動作させます。GPU が利用できない場合や、コスト効率の高い構成を希望する場合に、推論および学習に使用できます。

## 推論を実行する

`device_map` を指定しない場合、モデルはデフォルトで CPU にロードされます。また、アクセラレーターが利用できない場合、[pipeline()](/docs/transformers/main/ja/main_classes/pipelines#transformers.pipeline) は CPU を使用します。アクセラレーターも搭載されているマシンで CPU を使用するには、`device_map="cpu"` または `device="cpu"` を指定してください。

```py
from transformers import pipeline

generator = pipeline("text-generation", model="Qwen/Qwen3-0.6B", device="cpu")
print(generator("CPUs are", max_new_tokens=50, do_sample=False)[0]["generated_text"])
```

## Trainerで学習

bf16をサポートするCPU（最近のIntelやAMDのプロセッサなど）では、[PyTorchのAMP](https://docs.pytorch.org/docs/stable/amp)を使用してbf16混合精度トレーニングを行うことができ、メモリ使用量の削減とトレーニングの高速化を実現します。

以下の例は、1つのCPUが低速すぎる場合に複数のマシンを使用するケースまで、単一CPUから複数マシンまでの3つの構成をカバーしています。

- 単一の CPU
- 1台のマシン上で複数のプロセス（CPUソケットごとに1つ）
- 複数のマシンにまたがる複数のプロセス

単一ノードおよびマルチノードの例では、[Intel oneAPI HPC Toolkit](https://www.intel.com/content/www/us/en/developer/tools/oneapi/hpc-toolkit.html)の一部である[Intel MPI](https://www.intel.com/content/www/us/en/developer/tools/oneapi/mpi-library.html)の`mpirun`でプロセスを起動し、[Trainer](/docs/transformers/main/ja/main_classes/trainer#transformers.Trainer)は`gloo`バックエンド上でDDPを実行します。

`bf16=True` と `use_cpu=True` を [TrainingArguments](/docs/transformers/main/ja/main_classes/trainer#transformers.TrainingArguments) に設定するか、学習スクリプトに `--bf16` と `--use_cpu` を渡します。CPU では fp16 よりも数値的に安定しているため、bf16 を優先してください。

```py
from transformers import TrainingArguments

training_args = TrainingArguments(
    output_dir="./outputs",
    bf16=True,
    use_cpu=True,
)
```

デュアルソケットCPUでは、ソケットごとに1つのプロセスを実行します。メモリアクセスを各ソケット内にローカルに保つことで、スループットが向上します。以下の例では、`train.py`が`Trainer`の学習スクリプトである単一のマシン上で、ソケットごとに1プロセスずつ、2つのプロセスを起動します。

> [!TIP]
> `OMP_NUM_THREADS`は、1つのソケット上の物理コア数から、OS用に確保する1コアを引いた値に設定します。例えば、24コアのソケットでは`OMP_NUM_THREADS=23`と設定します。

```bash
export MASTER_ADDR=127.0.0.1
mpirun -n 2 -genv OMP_NUM_THREADS=23 \
python3 train.py \
 --output_dir ./outputs \
 --use_cpu \
 --bf16
```

`hostfile` に各ノードの IP アドレスを記載し、2 台のマシン(`node0` と `node1`)にまたがる 4 プロセスにトレーニングをスケールします。`-n 4` フラグはプロセスの総数を設定します。`-ppn 2` はノードあたりのプロセス数を 2(ソケットあたり 1 つ)に設定します。

メインプロセスとして機能する`node0`から、このスクリプトを実行してください。

> [!TIP]
> `OMP_NUM_THREADS`は、1つのソケット上の物理コア数から、OS用に確保する1コアを引いた値に設定します。例えば、24コアのソケットでは`OMP_NUM_THREADS=23`と設定します。

hostfile を作成し、各ノードの IP アドレスを記載します。

```bash
cat hostfile
xxx.xxx.xxx.xxx #node0 ip
xxx.xxx.xxx.xxx #node1 ip
```

次に、トレーニングスクリプトを実行します。

```bash
export MASTER_ADDR=xxx.xxx.xxx.xxx #node0 ip
mpirun -f hostfile -n 4 -ppn 2 \
 -genv OMP_NUM_THREADS=23 \
python3 train.py \
 --output_dir ./outputs \
 --use_cpu \
 --bf16
```

## CPUのパフォーマンスを調整する

CPU での学習時のオーバーヘッドを軽減するために、より高速なメモリアロケータと Intel の OpenMP ランタイムを事前読み込みします。`google-perftools`（`libtcmalloc` 用）と `intel-openmp` Python パッケージ（`libiomp5` 用）をインストールし、学習を開始する前に、両方のライブラリを `LD_PRELOAD` 環境変数に追加します。

`OMP_NUM_THREADS`には、各プロセスが使用できるコア数を設定します。CPUに制限が設けられたコンテナやクラスタジョブの場合、これは割り当てられたCPUユニットの数に相当するため、システムプロセス用にいくつかのコアを割り当てずに残しておく必要があります。

## 次のステップ

- モダンなIntelハードウェアにおけるBF16の性能について詳しく知りたい場合は、[Accelerating PyTorch Transformers with Intel Sapphire Rapids](https://huggingface.co/blog/intel-sapphire-rapids)のブログ記事をお読みください。
- マルチプロセスの例で使用されている分散戦略の詳細については、[DDP](./ddp)を参照してください。
- `OMP_NUM_THREADS` がパフォーマンスにどのように影響するかを学ぶには、PyTorch の [CPU スレッディング](https://docs.pytorch.org/docs/stable/notes/cpu_threading_torchscript_inference.html) に関するメモをお読みください。
- Kubernetes上で分散CPUトレーニングを実行するには、Kubeflowの[PyTorchJobガイド](https://www.kubeflow.org/docs/components/training/user-guides/pytorch/)を参照してください。

