llama.cppをDocker-composeでビルドから構築する方法

## はじめに

### llama.cppとは

llama.cppは、Meta（旧Facebook）が開発したLLaMA（Large Language Model Meta AI）モデルを、C/C++で実装したオープンソースプロジェクトです。このプロジェクトは、高性能な言語モデルを様々なハードウェアで動作させることを目的としています。

---

こちらの記事もおすすめ

https://hamaruki.com/llama-cpp-wandb-gemma-2-9b-elyza-tasks-performance/

https://hamaruki.com/llama-cpp-wandb-karakuri-lm-elyza-tasks-performance/

### なぜDocker-composeを使うのか

Docker-composeを使用することで、llama.cppの環境構築を簡単に行うことができます。複雑な依存関係や環境設定を、簡単に再現可能な形で管理できるのが大きな利点です。

## 準備

### 必要なツール

- Docker
- Docker-compose
- Git（ソースコードの取得に使用）

### ディレクトリ構造の作成

まず、プロジェクトのディレクトリを作成しましょう。

```bash
mkdir llama-cpp-project
cd llama-cpp-project
```

## Docker-compose.ymlの作成

### 基本構成

`docker-compose.yml`ファイルを作成し、以下の内容を記述します。

```yaml
version: '3.8'
services:
  app:
    build: .
    volumes:
      - .:/app
    tty: true
    env_file:
      - .env
    extra_hosts:
      - "host.docker.internal:host-gateway"

  llama-cpp:
    build: 
      context: .
      dockerfile: Dockerfile.llama
    volumes:
      - ./models:/models
    ports:
      - "8080:8080"
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [ gpu ]
    tty: true
    command: >
      ./llama-server
      -m /models/mixtral-8x7b-v0.1.Q4_K_M.gguf
      -c 32000
      --port 8080
      --host 0.0.0.0
      -n -1
      --n-gpu-layers 10
```

### 各設定の説明

- `app`サービス: 開発環境用のコンテナです。
- `llama-cpp`サービス: llama.cppを実行するためのコンテナです。
- `volumes`: ホストとコンテナ間でファイルを共有します。
- `ports`: ホストの8080ポートをコンテナの8080ポートにマッピングします。
- `deploy`: NVIDIAのGPUを使用するための設定です。
- `command`: llama-serverを起動するコマンドです。

## Dockerfileの作成

### Dockerfile.llamaの内容

`Dockerfile.llama`という名前でファイルを作成し、以下の内容を記述します。

```dockerfile
ARG CUDA_IMAGE="12.5.0-devel-ubuntu22.04"
FROM nvidia/cuda:${CUDA_IMAGE}

ENV HOST 0.0.0.0

RUN apt-get update && apt-get upgrade -y \
    && apt-get install -y git build-essential \
    python3 python3-pip gcc wget \
    ocl-icd-opencl-dev opencl-headers clinfo \
    libclblast-dev libopenblas-dev \
    && mkdir -p /etc/OpenCL/vendors && echo "libnvidia-opencl.so.1" > /etc/OpenCL/vendors/nvidia.icd

WORKDIR /app

RUN git clone https://github.com/ggerganov/llama.cpp.git
WORKDIR /app/llama.cpp

ENV CUDA_DOCKER_ARCH=all
ENV LLAMA_CUBLAS=1

RUN python3 -m pip install --upgrade pip pytest cmake scikit-build setuptools fastapi uvicorn sse-starlette pydantic-settings starlette-context

RUN mkdir build && cd build && \
    cmake .. -DGGML_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES=all

RUN cd build && \
    make VERBOSE=1 -j4 || \
    (echo "Make failed. Retrying with more details..." && \
    make VERBOSE=1 && \
    echo "If make succeeded this time, there might be a concurrency issue.") && \
    cp bin/* ..

CMD ["/bin/bash"]
```

### Dockerfileの説明

- CUDA対応のUbuntuイメージを使用
- 必要なパッケージのインストール
- llama.cppリポジトリのクローン
- ビルド環境の設定
- CMakeとmakeによるビルド

## ビルドと実行

### Docker-composeによるビルド

以下のコマンドでDocker-composeによるビルドを実行します。

```bash
docker-compose build
```

### コンテナの起動

ビルドが完了したら、以下のコマンドでコンテナを起動します。

```bash
docker-compose up
```

## llama.cppの使用

### モデルの準備

llama.cppを使用するには、適切なモデルファイルが必要です。`models`ディレクトリに配置してください。

### サーバーの起動

コンテナ起動時に自動的にllama-serverが起動します。`http://localhost:8080`でアクセス可能です。

### APIの利用

RESTful APIを通じて、モデルとやり取りができます。例えば、以下のようなcURLコマンドで利用できます。

```bash
curl -X POST http://localhost:8080/v1/completions \
     -H "Content-Type: application/json" \
     -d '{"prompt": "Once upon a time", "max_tokens": 50}'
```

## トラブルシューティング

### GPUが認識されない場合

- NVIDIAドライバーが正しくインストールされているか確認
- `nvidia-smi`コマンドでGPUの状態を確認

### ビルドエラーが発生する場合

- Dockerfileの`make`コマンドのオプションを調整
- 必要に応じて`-j`オプションの数値を減らす

## まとめ

本記事では、llama.cppをDocker-composeを使ってビルドから構築する方法を解説しました。この方法を使えば、環境に依存せず、簡単にllama.cppを利用することができます。大規模言語モデルの実験や開発に、ぜひ活用してみてください。

## 参考リンク

- [llama.cpp GitHub リポジトリ](https://github.com/ggerganov/llama.cpp)
- [Docker公式ドキュメント](https://docs.docker.com/)
- [NVIDIA Container Toolkit](https://github.com/NVIDIA/nvidia-docker)

この記事を通じて、llama.cppの環境構築がより簡単になることを願っています。質問やフィードバックがあれば、お気軽にコメントしてください。