2025/01/30

日本語追加学習DeepSeek R1をArch Linux+RTX4070で動かしてみる

サイバーエージェントのDeepSeek日本語追加学習モデルを試してみます。

はじめに

サイバーエージェントが日本語を追加学習させたDeepSeek R1を発表しました。 さっそく試してみます。

悲報(朗報) [追記]

これのパラメータ数が低いモデルがありました。一通り見た気になってたんですが、気付かなかった、、
最強のGPUを持ってる人意外はこちらを使ってください。 量子化するとめっちゃいい感じに動きます。

今回動かす環境はこちら

fastfetch

見てわかる通り、Arch LinuxといってもWSLです。

AURヘルパーとして、paruを使用しています。

Python等は入ってる前提で行きます。

Nvidia関連のセットアップ

パッケージをインストールします。

paru -S nvidia nvidia-utils opencl-nvidia

もしかしたら全部必要ではないかもしれないです。また、足りないパッケージがある可能性もあります。

GPUがしっかり読み込まれてるか確認します。

$ nvidia-smi
Tue Jan 28 23:24:49 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 565.77                 Driver Version: 566.14         CUDA Version: 12.7     |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA GeForce RTX 4070        On  |   00000000:01:00.0  On |                  N/A |
| 30%   48C    P0             34W /  200W |    2496MiB /  12282MiB |     14%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+

+-----------------------------------------------------------------------------------------+
| Processes:                                                                              |
|  GPU   GI   CI        PID   Type   Process name                              GPU Memory |
|        ID   ID                                                               Usage      |
|=========================================================================================|
|    0   N/A  N/A        26      G   /Xwayland                                   N/A      |
+-----------------------------------------------------------------------------------------+

Pythonで動かす

無謀なのはわかっていますが、念のため動かしてみます。

main.py
from transformers import AutoModelForCausalLM, AutoTokenizer, TextStreamer

model = AutoModelForCausalLM.from_pretrained(
    "cyberagent/DeepSeek-R1-Distill-Qwen-32B-Japanese",
    device_map="auto",
    torch_dtype="auto",
)
tokenizer = AutoTokenizer.from_pretrained(
    "cyberagent/DeepSeek-R1-Distill-Qwen-32B-Japanese"
)
streamer = TextStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)

messages = [
    {"role": "user", "content": "AIによって私たちの暮らしはどのように変わりますか?"}
]

input_ids = tokenizer.apply_chat_template(
    messages, add_generation_prompt=True, return_tensors="pt"
).to(model.device)
output_ids = model.generate(
    input_ids, max_new_tokens=4096, temperature=0.7, streamer=streamer
)

こちらのコードはHuggingFaceのUsageのものです。

python -m venv venv
source venv/bin/activate
pip install transformers torch
python main.py

鬼長いダウンロードが始まります。約5GBのファイルを14個ダウンロードします。
うちはVDSLなので、めちゃくちゃ遅くて辛いです。。

まあダウンロードしたところで、自分のPCだと実行も遅すぎてとても実用的ではありませんでした。

こちらの実行結果は2回目の実行です。 ダウンロード抜きなので、約3時間程でした。

<think>タグがあります。 そこで思考してるっぽいですね。(それがR1の特徴らしいです。)

llama.cppで動かす

モデルの変換

Ollamaはsafetensorsには対応していないので、GGUFに変換する必要があります。

llama.cppというツールを使います。

こちらのリポジトリをクローンします。

gh repo clone ggerganov/llama.cpp

ディレクトリを移動したら例のごとく仮想環境を作って ライブラリをインストールします。

cd llama.cpp
python -m venv venv
source venv/bin/activate
pip install -r requirements/requirements-convert_hf_to_gguf.txt

自分はここでこんなエラーがでました。

ERROR: Could not find a version that satisfies the requirement torch~=2.2.1 (from versions: 2.5.0, 2.5.0+cpu, 2.5.1, 2.5.1+cpu, 2.6.0+cpu)
ERROR: No matching distribution found for torch~=2.2.1

pyenvで少し古いバージョンを指定したら上手くいきました。

$ python --version
Python 3.13.1
$ pyenv local 3.10.13
$ python --version
Python 3.10.13

早速変換していきます。 スナップショットのハッシュは適宜置き換えてください。

# 作業dir(llama.cppの親dir)にmodel格納用dirを作成しておきます
mkdir ../model

./convert_hf_to_gguf.py  ~/.cache/huggingface/hub/models--cyberagent--DeepSeek-R1-Distill-Qwen-32B-Japanese/snapshots/32c4a6155dcc093944b58e0a3d5b29ed96907564 --outfile ../model/deepseek-jp.gguf

量子化する

先ほどのconvert_hf_to_gguf.pyでも--outtype q8_0で量子化できますが、 今回は4bitで量子化したいので、別で行います。

先ほどcloneしたllama.cppを自前ビルドしてもいいです。
cliの方が便利なので、今回はAURからいれちゃいます。

cudaバージョンを入れます。

paru -S llama.cpp-cuda

ヘルプを見ると、いろいろな量子化方式があります。
今回は一番使われてるぽいQ4_K_Mを使用します。

$ llama-quantize -h
usage: llama-quantize [--help] [--allow-requantize] [--leave-output-tensor] [--pure] [--imatrix] [--include-weights] [--exclude-weights] [--output-tensor-type] [--token-embedding-type] [--override-kv] model-f32.gguf [model-quant.gguf] type [nthreads]

  --allow-requantize: Allows requantizing tensors that have already been quantized. Warning: This can severely reduce quality compared to quantizing from 16bit or 32bit
  --leave-output-tensor: Will leave output.weight un(re)quantized. Increases model size but may also increase quality, especially when requantizing
  --pure: Disable k-quant mixtures and quantize all tensors to the same type
  --imatrix file_name: use data in file_name as importance matrix for quant optimizations
  --include-weights tensor_name: use importance matrix for this/these tensor(s)
  --exclude-weights tensor_name: use importance matrix for this/these tensor(s)
  --output-tensor-type ggml_type: use this ggml_type for the output.weight tensor
  --token-embedding-type ggml_type: use this ggml_type for the token embeddings tensor
  --keep-split: will generate quantized model in the same shards as input
  --override-kv KEY=TYPE:VALUE
      Advanced option to override model metadata by key in the quantized model. May be specified multiple times.
Note: --include-weights and --exclude-weights cannot be used together

Allowed quantization types:
   2  or  Q4_0    :  4.34G, +0.4685 ppl @ Llama-3-8B
   3  or  Q4_1    :  4.78G, +0.4511 ppl @ Llama-3-8B
   8  or  Q5_0    :  5.21G, +0.1316 ppl @ Llama-3-8B
   9  or  Q5_1    :  5.65G, +0.1062 ppl @ Llama-3-8B
  19  or  IQ2_XXS :  2.06 bpw quantization
  20  or  IQ2_XS  :  2.31 bpw quantization
  28  or  IQ2_S   :  2.5  bpw quantization
  29  or  IQ2_M   :  2.7  bpw quantization
  24  or  IQ1_S   :  1.56 bpw quantization
  31  or  IQ1_M   :  1.75 bpw quantization
  36  or  TQ1_0   :  1.69 bpw ternarization
  37  or  TQ2_0   :  2.06 bpw ternarization
  10  or  Q2_K    :  2.96G, +3.5199 ppl @ Llama-3-8B
  21  or  Q2_K_S  :  2.96G, +3.1836 ppl @ Llama-3-8B
  23  or  IQ3_XXS :  3.06 bpw quantization
  26  or  IQ3_S   :  3.44 bpw quantization
  27  or  IQ3_M   :  3.66 bpw quantization mix
  12  or  Q3_K    : alias for Q3_K_M
  22  or  IQ3_XS  :  3.3 bpw quantization
  11  or  Q3_K_S  :  3.41G, +1.6321 ppl @ Llama-3-8B
  12  or  Q3_K_M  :  3.74G, +0.6569 ppl @ Llama-3-8B
  13  or  Q3_K_L  :  4.03G, +0.5562 ppl @ Llama-3-8B
  25  or  IQ4_NL  :  4.50 bpw non-linear quantization
  30  or  IQ4_XS  :  4.25 bpw non-linear quantization
  15  or  Q4_K    : alias for Q4_K_M
  14  or  Q4_K_S  :  4.37G, +0.2689 ppl @ Llama-3-8B
  15  or  Q4_K_M  :  4.58G, +0.1754 ppl @ Llama-3-8B
  17  or  Q5_K    : alias for Q5_K_M
  16  or  Q5_K_S  :  5.21G, +0.1049 ppl @ Llama-3-8B
  17  or  Q5_K_M  :  5.33G, +0.0569 ppl @ Llama-3-8B
  18  or  Q6_K    :  6.14G, +0.0217 ppl @ Llama-3-8B
   7  or  Q8_0    :  7.96G, +0.0026 ppl @ Llama-3-8B
   1  or  F16     : 14.00G, +0.0020 ppl @ Mistral-7B
  32  or  BF16    : 14.00G, -0.0050 ppl @ Mistral-7B
   0  or  F32     : 26.00G              @ 7B
          COPY    : only copy tensors, no quantizing

ということで、先ほどGGUFファイルを生成したディレクトリに移動してください。

移動したら、量子化します。

$ llama-quantize deepseek-jp.gguf Q4_K_M

$ ls
deepseek-jp.gguf  ggml-model-Q4_K_M.gguf

$ mv ggml-model-Q4_K_M.gguf deepseek-jp-Q4_K_M.gguf

普通にCPU全開で動きましたが、約5分くらいで終わりました。
わかりやすいように名前を変えておきました。

$ ll
total 80G
-rw-r--r-- 1 runfunrun runfunrun 62G Jan 29 18:18 deepseek-jp.gguf
-rw-r--r-- 1 runfunrun runfunrun 19G Jan 29 19:21 deepseek-jp-Q4_K_M.gguf

容量は結構減りました。

動かしてみる

CLIのインタラクションモードで動かしてみます。

今回の場合--n-gpu-layersを最大65まで設定できます。 タスクマネージャーを見て、VRAMと相談して決めてください。

何回か試してみて32が良さそうだったので、32でいきます。
といってもかなり遅いです。特に思考時間があるので長く感じます。

llama-cli -m deepseek-jp-Q4_K_M.gguf --interactive --n-gpu-layers 32

最初にPythonで投げたプロンプトと同じプロンプトを投げてみました。
実行時間は約11分でした。 大幅に短くなったとはいえ、実用はかなり厳しいです。

Ollamaで動かす

Ollamaのセットアップ

一旦プロジェクトルートに戻っておきます。(model/があるdir)

Modelfileを作成します。(Dockerfileみたいですね)
なんかいろいろ書けるみたいですが、今回はこれで行きます。

echo "FROM ./model/deepseek-jp-Q4_K_M.gguf" > Modelfile
Modelfile
FROM ./model/deepseek-jp-Q4_K_M.gguf

このファイルを元にollamaにモデルを作成することになります。

今回、ollamaを直接インストールします。
cuda無しバージョンはGPUを使ってくれないので注意してください。

paru -S ollama-cuda

余談ですが、なぜDockerを使わないか念の為言っておきます。
正直なところ、Docker x Nvidia x WSL2(しかもArch Linux)の環境構築で骨が折れました。 いろいろググってやってみたんですが、ダメでした。
わかる人、マジで教えてほしいです。

$ docker run --rm --privileged --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi
docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error running prestart hook #0: exit status 1, stdout: , stderr: Auto-detected mode as 'legacy'
nvidia-container-cli: mount error: failed to add device rules: open /sys/fs/cgroup/devices/devices.allow: no such file or directory: unknown.

Dockerの話は忘れて、早速起動させます。

sudo systemctl start ollama.service

念のため、statusを見てみます。

$ systemctl status ollama.service
 ollama.service - Ollama Service
     Loaded: loaded (/usr/lib/systemd/system/ollama.service; disabled; preset: disabled)
     Active: active (running) since Wed 2025-01-29 21:48:52 JST; 2s ago
 Invocation: a8b59ff35eaa4cb7a2c4473edcf7c0f2
   Main PID: 207758 (ollama)
        CPU: 236ms
     CGroup: /system.slice/ollama.service
             └─207758 /usr/bin/ollama serve

ばっちりです。

ollamaにモデルを作ります。(というかコピーです。)

ollama create deepseek-jp-Q4_K_M -f Modelfile

これでインタラクティブモードで使えます。

ollama run deepseek-jp-Q4_K_M

Open WebUIのセットアップ

こちらもAURからいれちゃいます。

paru -S open-webui

起動するだけです。

sudo systemctl start open-webui.service

WebUIからOllamaを使う

http://localhost:8080にアクセスします。 初回は画面の案内通りにユーザーを作ってください。

同じプロンプトを入れてみます。

webui1

webui2

webui3

こんな感じの結果になりました。

最後に

遅すぎたので、今度別のパラメータのDeepSeekでリベンジします。
日本語追加学習モデルは一旦諦めます。
→ 冒頭で言った通りパラメータ数14Bのモデルを量子化するとめっちゃいい感じです。
出力や実行時間は変わりますが、14Bのモデルでも使い方は同じなので、良かったら参考にしてください。

性能はこれから使って確かめたいと思います。

ではまた。

最終更新日:2026/01/20