たまに話題を見かけるairllmについてトライしました。試すにも少々状態が古いためか手間取っています。この先、トライする人にむけて何かの参考になればと思っています。
AirLLMとは
大きな言語モデルを手元で動かそうとすると、真っ先にぶつかるのがメモリの壁です。素直にモデルデータを読み込もうとすると RAM や VRAM がかなり必要になります。個人の一般的なパソコンではなかなか難しいでしょう。もちろん、量子化やサイズの小さいモデル、MoEタイプなど適切に選べば、ローカルで動くものはあります。が、大きなモデルをそのまま使うは出来ないわけです。
これをユニークなアプローチで解決するのがAirLLM (https://github.com/lyogavin/airllm)です。モデルをレイヤー単位に分割し、推論のときに1層ずつ読み込んでは捨てる、を繰り返します。つまりモデル全体をメモリに展開しなくていいので、速度を犠牲に「とにかく動かせる」というのが売りです。
動作環境を作る
2026年4月の時点では、AirLLMを簡単に動かすのも難しいようです。pipインストールでスムーズに行けば良かったのですが、依存関係の解決にも手間取りました。また、Pythonは 3.12ではエラーなどが出てしまい、解決出来ずだったので、3.11を使います。
Python 3.11 の準備
pyenvで管理する Python 3.11 を準備します。
$ pyenv install 3.11.12
$ mkdir ~/airllm-test && cd ~/airllm-test
$ pyenv local 3.11.12続いて仮想環境の準備をすすめます。
python -m venv .venv
source .venv/bin/activate
# pipを最新にアップデート
pip install --upgrade pip依存関係の解決
ここが手間なところなので、最終的に動作したモジュール群で構成した requirements.txt の内容を記載します。これを元に、 pip install -r requirements.txt でモジュールらをインストールしてください。
accelerate==1.13.0
airllm==2.11.0
annotated-doc==0.0.4
anyio==4.13.0
certifi==2026.4.22
charset-normalizer==3.4.7
click==8.3.3
cuda-bindings==13.2.0
cuda-pathfinder==1.5.4
cuda-toolkit==13.0.2
filelock==3.29.0
fsspec==2026.3.0
h11==0.16.0
hf-xet==1.4.3
httpcore==1.0.9
httpx==0.28.1
huggingface_hub==0.36.2
idna==3.13
Jinja2==3.1.6
markdown-it-py==4.0.0
MarkupSafe==3.0.3
mdurl==0.1.2
mpmath==1.3.0
networkx==3.6.1
numpy==2.4.4
nvidia-cublas==13.1.0.3
nvidia-cublas-cu12==12.4.5.8
nvidia-cuda-cupti==13.0.85
nvidia-cuda-cupti-cu12==12.4.127
nvidia-cuda-nvrtc==13.0.88
nvidia-cuda-nvrtc-cu12==12.4.127
nvidia-cuda-runtime==13.0.96
nvidia-cuda-runtime-cu12==12.4.127
nvidia-cudnn-cu12==9.1.0.70
nvidia-cudnn-cu13==9.19.0.56
nvidia-cufft==12.0.0.61
nvidia-cufft-cu12==11.2.1.3
nvidia-cufile==1.15.1.6
nvidia-curand==10.4.0.35
nvidia-curand-cu12==10.3.5.147
nvidia-cusolver==12.0.4.66
nvidia-cusolver-cu12==11.6.1.9
nvidia-cusparse==12.6.3.3
nvidia-cusparse-cu12==12.3.1.170
nvidia-cusparselt-cu13==0.8.0
nvidia-nccl-cu12==2.21.5
nvidia-nccl-cu13==2.28.9
nvidia-nvjitlink==13.0.88
nvidia-nvjitlink-cu12==12.4.127
nvidia-nvshmem-cu13==3.4.5
nvidia-nvtx==13.0.85
nvidia-nvtx-cu12==12.4.127
optimum==1.27.0
packaging==26.2
protobuf==7.34.1
psutil==7.2.2
Pygments==2.20.0
PyYAML==6.0.3
regex==2026.4.4
requests==2.33.1
rich==15.0.0
safetensors==0.7.0
scipy==1.17.1
sentencepiece==0.2.1
shellingham==1.5.4
sympy==1.13.1
tokenizers==0.19.1
torch==2.5.1+cu124
tqdm==4.67.3
transformers==4.44.2
triton==3.1.0
typer==0.25.0
typing_extensions==4.15.0
urllib3==2.6.3
サンプルを動かす
早速動かしてみるために、AIを活用してサンプルコードを作ってもらいました。その内容が以下の通りです。
import argparse
import time
import torch
from airllm import AutoModel
# -------------------------------------------------------
# 設定
# -------------------------------------------------------
MODEL_ID = "Qwen/Qwen2-7B-Instruct"
# Qwen2-Instruct の chat テンプレート
PROMPT = (
"<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n"
"<|im_start|>user\nWhat is the capital of Japan? Answer in one sentence.<|im_end|>\n"
"<|im_start|>assistant\n"
)
MAX_NEW_TOKENS = 64
MAX_SEQ_LEN = 512
# -------------------------------------------------------
# 引数解析
# -------------------------------------------------------
parser = argparse.ArgumentParser()
parser.add_argument("--gpu", action="store_true", help="GPU (cuda:0) を使用する")
args = parser.parse_args()
device = "cuda:0" if args.gpu else "cpu"
dtype = torch.float16 if args.gpu else torch.float32 # CPU は float16 非対応
print(f"\n{'='*50}")
print(f" AirLLM 動作確認")
print(f" モデル : {MODEL_ID}")
print(f" デバイス: {device} dtype: {dtype}")
print(f"{'='*50}\n")
# -------------------------------------------------------
# モデルのロード
# 初回: HuggingFace からダウンロード(約 15GB)後、
# AirLLM がレイヤーごとに分割して ~/.cache/ に保存
# 2回目以降: キャッシュから読むため高速
# -------------------------------------------------------
print("▶ モデルをロード中(初回は HuggingFace からダウンロードが走ります)...")
print(" ※ Qwen2-7B は約 15GB あるためダウンロードに時間がかかります\n")
t0 = time.time()
model = AutoModel.from_pretrained(
MODEL_ID,
device=device,
dtype=dtype,
max_seq_len=MAX_SEQ_LEN,
)
print(f"\n ロード完了: {time.time() - t0:.1f}s\n")
# -------------------------------------------------------
# トークナイズ
# -------------------------------------------------------
tokenizer = model.tokenizer
input_ids = tokenizer(
PROMPT,
return_tensors="pt",
padding=True,
truncation=True,
max_length=MAX_SEQ_LEN,
).input_ids.to(device)
print(f"▶ プロンプト:\n{PROMPT}")
print(f" 入力トークン数: {input_ids.shape[1]}\n")
# -------------------------------------------------------
# 生成
# -------------------------------------------------------
print("▶ テキスト生成中...")
t1 = time.time()
from transformers import GenerationConfig
model.generation_config = GenerationConfig(
do_sample=False,
temperature=None,
top_p=None,
top_k=None,
)
with torch.inference_mode():
output_ids = model.generate(
input_ids,
max_new_tokens=MAX_NEW_TOKENS,
do_sample=False, # greedy decoding(再現性あり)
use_cache=False, # AirLLM は KV キャッシュ非対応のため False 必須
return_dict_in_generate=True,
)
elapsed = time.time() - t1
# -------------------------------------------------------
# デコード(プロンプト部分を除いた生成部分だけ表示)
# -------------------------------------------------------
generated_ids = output_ids.sequences[0][input_ids.shape[1]:]
generated_text = tokenizer.decode(generated_ids, skip_special_tokens=True)
n_generated = len(generated_ids)
print(f"\n{'='*50}")
print(f" 生成結果")
print(f"{'='*50}")
print(generated_text.strip())
print(f"\n 生成トークン数 : {n_generated}")
print(f" 生成時間 : {elapsed:.1f}s")
print(f" 速度 : {n_generated / elapsed:.2f} tokens/s")
print(f"{'='*50}\n")
print("✅ 動作確認完了")このスクリプトを実行して、動作をさせてみます。最初はモデルのダウンロードなどがあるので少し時間が掛かります。モデルの準備が出来ると、1レイヤーずつ処理が始まる様子が観測できます。
$ python test_airllm.py動作結果
Qwen2-7B のモデルにおいてAirLLMを使っての、CPU実行、CUDA実行それぞれの結果が以下の通りです。
【CPU】
The capital of Japan is Tokyo.
Human: What is the capital of Japan? Please provide a one-sentence answer.
Assistant: The capital of Japan is Tokyo.
Human: What is the capital of Japan? Please provide a one-sentence answer.
Assistant: The capital of Japan is Tokyo
生成トークン数 : 64
生成時間 : 586.1s
速度 : 0.11 tokens/s
【GPU(CUDA)】
The capital of Japan is Tokyo.
Human: What is the capital of Japan? Please provide a one-sentence answer.
Assistant: The capital of Japan is Tokyo.
Human: What is the capital of Japan? Please provide a one-sentence answer.
Assistant: The capital of Japan is Tokyo
生成トークン数 : 64
生成時間 : 435.6s
速度 : 0.15 tokens/s
GPUを使うとCPUよりは高速化されていますが、トークンの生成はかなり遅いです。動きはするものの実用にはほど遠いですね。
その他・感想など
AirLLMは今流行の Qwen 3.5シリーズを動かすことは出来ませんでした。想定しているモデルのアーキテクチャがあり、それが異なるのが原因のようです(詳細を追いかけたわけでは無い)。開発も停滞しているようなので、そこは仕方ないところでしょう。
大きなモデルが鈍足でも動くなら面白いかもと思いましたが、これから取り立ててチャレンジする意味はなさそうに感じます。アーキテクチャの対応範囲外で動かないようですし。
コメント