📌

ローカルLLMのシステムコールの使用を確認してみる

に公開

はじめに

LLMを使用する際のPythonライブラリをシステムコールまで掘り下げると、どうなるかを試してみました。

マシンスペック

MacBook Air M2 arm64

事前知識

システムコール

下記の記事で簡単に説明しています。
https://zenn.dev/ka_kan/articles/b4ac244e17008e

準備

Dockerの準備

Dockerファイルの準備をします。

FROM ubuntu:24.04
RUN apt-get update && apt-get install -y \
    build-essential cmake git curl wget ca-certificates \
    python3 python3-venv python3-pip strace lsof \
    libcurl4-openssl-dev
WORKDIR /workspace
RUN git clone --depth=1 https://github.com/ggml-org/llama.cpp.git

Dockerファイルのビルドを行います。

docker build -t llmtrace .

Dockerコンテナに接続します。

docker run --rm -it -v "$(pwd)":/data llmtrace bash

モデルの取得

mkdir -p /workspace/models
wget -O /workspace/models/qwen2-0_5b-instruct-q4_0.gguf \
  https://huggingface.co/Qwen/Qwen2-0.5B-Instruct-GGUF/resolve/main/qwen2-0_5b-instruct-q4_0.gguf

llamaのビルド

cd /workspace/llama.cpp
mkdir build && cd build
cmake .. -DLLAMA_BUILD_EXAMPLES=ON
cmake --build . -j$(nproc)

llama-cpp-pythonのインストール

python3 -m venv /workspace/venv
source /workspace/venv/bin/activate

pip install --upgrade pip
pip install llama-cpp-python

実験

C++を掘り下げる

strace -c -f /workspace/llama.cpp/build/bin/llama-cli \
  -m /workspace/models/qwen2-0_5b-instruct-q4_0.gguf \
  -p "Hi"

llama-cpp-pythonを掘り下げる

source /workspace/venv/bin/activate
strace -c -f python - <<'PY'
from llama_cpp import Llama
llm = Llama(model_path="/workspace/models/qwen2-0_5b-instruct-q4_0.gguf")
print(llm("Hi")["choices"][0]["text"])
PY

結果

C++を掘り下げる

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ------------------
 99.76   15.104652         205     73337     25447 futex
  0.07    0.011237          69       161           mmap
  0.07    0.010766          52       204           write
  0.04    0.005860           3      1512         1 read
  0.01    0.001311          14        92        13 openat
 ...略
------ ----------- ----------- --------- --------- ------------------
100.00   15.140260         199     76022     25484 total

llama-cpp-pythonを掘り下げる

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ------------------
 98.14    1.548201          82     18674       720 futex
  0.51    0.008047          45       176           mmap
  0.39    0.006143          63        97           munmap
  0.25    0.003961           2      1920           read
  0.12    0.001870           2       909        81 newfstatat
  0.11    0.001688           4       407           write
...略
------ ----------- ----------- --------- --------- ------------------
100.00    1.577615          64     24488      1042 total

所感

ローカルでllamaを呼び出すと98-99%futexを使用していることから、スレッド同期が処理の大半を占有していると伺えます。ゆえに単純にマシンの性能を上げてスレッドを増やして実行しても、目覚まし性能改善は見込め無さそうです。適切なスレッド数に制限し、無駄な同期処理を減らすことが、性能向上に繋がる可能性がありそうだと感じました。

まとめ

今回はllamaを実行して簡単な「Hi」という文字だけを送ってstraceでシステムコールを追いました。
今後はLLMの性能改善にコンピュータの側からアプローチができるか否かを試してみたいと思いました。

Discussion