流行りのDeep Seek R1, ローカルGPUで動かしcline連携してみた

# はじめに
みなさん「Deep Seek」はご存じですか？
DeepSeekは[中国のAI企業](https://www.deepseek.com/) で、2025/1/20に同社の最新のLLM「DeepSeek-R1」を発表しました。
DeepSeekがもたらしたインパクトは、これまで大規模LLMを引っ張ってきたOpenAIやAnthropicなどが提供するLLMモデルに比べ圧倒的に安価ということで、Deep Seek R-1の開発費はChatGPTの10分の1とのニュースも流れてきます。
OpenAIやその他多くの大規模LLMがクローズドであるのに対して、DeepSeekはオープンソースでモデルを公開してくれているのが特徴です。

DeepSeekが何者か？などはものすごい速度でニュースやブログ記事が出されており、テクノロジーの進歩の早さもさる程ながら、情報の早さも一瞬で広がるんだなと感心している私ですが、今回はDeepSeek R1モデルを自作PCに入れ、ローカルLLMとして動かしてみようと思います。

また、生成AIによるAIコーディングを行える「**Cline**」というものも使ったことがなかったので、これを機にローカルLLMでClineを動かし、開発効率を爆上げしてやろうと思います。

:::note info
LLMをローカルにインストールする大きなメリットは無料でAIを使用できるようになることです。
LLMをAPI経由で使用する際は回数制限や従量課金がなされますが、ローカル環境にLLMを入れることでこれらから解放されてLLMが自由に使い放題になるという点があります
:::

## 使用しているPC

* OS：Windows11 Pro (23H2)
* CPU：intel core-i7 14700F
* GPU：Nvidia RTX4070(12GB)
* メモリ：32GB

特にGPUは高性能なもののほうが高速に動作し快適に使用できます

# LLMモデルのダウンロード
まず最初はLLMモデルのダウンロードから行う必要があります。
自分はLLMの`.safetensors`や`.gguf`などがどういうものか詳しくは知りません。簡単に調べると以下のようなことらしいです。

### safetensors

```
`.safetensors`は機械学習モデルのデータを保存・読み込むための新しいファイル形式です。従来のPyTorchで使われていた.pthや.pt（pickleフォーマット）の問題点を解決するために、Hugging Face社が開発しました。

簡単に言うと以下のような特徴があります：

🔒 安全: モデルファイルに悪意のあるコードが含まれる心配がありません
⚡ 高速: 従来形式と比べて約100倍速く読み込めます
💾 効率的: 必要な部分だけを読み込めるので、メモリを効率的に使えます
🔄 互換性: PyTorch、TensorFlow、JAXなど、主要なフレームワーク間で互換性があります
※https://qiita.com/yonaka15/items/e738a33cbbac1ddc0402
```

### gguf
```

`.gguf`は、ローカルで大規模言語モデル（LLM）を動かす際によく用いられる`llama.cpp`で動かす際に用いられるファイル形式です。`llama.cpp`とはMeta社のLLMの1つであるLlamaモデルの重みを量子化という技術でより低精度の離散値に変換することで推論の高速化を図るツールだそうです。
数多くのLLMが公開されているHuggingFaceを介したモデル配布で一般的な「safetensors」形式のモデルを直接読み込むことはできないため、言語モデルを`llama.cpp`で扱うためにはこの`.gguf`フォーマットへの変換が必要となります。
```

そういえば自作PCの中でStable diffusionを動かしたときも`.safetensors`拡張子を見ていましたが何者かよく理解しておらず、自分の知識は`.pth`や`.onnx`で止まっていました。AIの進化及びモデルの巨大化とともにモデルファイルも進化しているのですね。

Deep Seek R-1も以下のHuggingFace上で公開されています。（https://huggingface.co/deepseek-ai/DeepSeek-R1)

なので、まずはローカルで動かすための`.gguf`ファイルを探す必要があります。
今回はサイバーエージェントが公開している[日本語対応の`.safetensors`](https://huggingface.co/bluepen5805/DeepSeek-R1-Distill-Qwen-14B-Japanese-gguf/tree/main)から作られている以下の`DeepSeek-R1-Distill-Qwen-14B-Japanese-Q4_K_M.gguf`を使用しようと思います。

https://huggingface.co/bluepen5805/DeepSeek-R1-Distill-Qwen-14B-Japanese-gguf/tree/main

ちなみに、モデルにある`Q4`や`Q5`などは量子化ビット数であり、この値が小さいほど少ないビット数で表現（データが圧縮）されることになります。よって**低ビット量子化はモデルが軽量となる**ので、動かない、もしくは動くけど動作が遅い場合はより小さいものを選択するようにしてください。

## llama.cppのインストール
すでにLLMをローカルで動かすなどをしてllama.cppがインストールされている場合はスキップしてかまいません。

[GitHub上の公開ページ](https://github.com/ggerganov/llama.cpp/releases)から以下の2つの`.zip`ファイルをインストールし任意のフォルダに回答します。

* cudart-llama-bin-win-cu12.4-x64.zip (CUDAバージョンを確認)
* llama-b4628-bin-win-cuda-cu12.4-x64.zip
    * bxxxxの数値はその時使うバージョンに合わせて下さい

## LLMの実行
上記をダウンロードしたらPowerShellを起動し以下のコマンドを打ちます。

``` PowerShell
.\llama-server.exe -m ..\gguf_models\DeepSeek-R1-Distill-Qwen-14B-Japanese-Q4_K_M.gguf
```
llama-server.exeを実行。引数として`-m path_to.gguf`を入力する

うまくいくと`main: server is listening on http://127.0.0.1:8080 - starting the main loop`と出るはずなのでWebブラウザから`http://127.0.0.1:8080`にアクセスしチャットを実施する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604944/5c687c15-9930-1841-53a5-036b51fe220e.png)

ここまでで、ローカル環境でLLMを動かすことができました。

## Ollamaのインストール
OllamaはLLMをローカル環境で立ち上げて実行することができるオープンソースのアプリケーションであり、インターネット接続長くても高度なLLMを使用することができるようになります。llama.cppをベースに開発されており、LLMをWebAPI経由で使用するのではなくローカル環境で利用することで、データ漏えいリスクを低減することができ、さらにAPI利用コストを削減（無料）できたりと多くのメリットを得ることができます。

以下のページからダウンロードします。

https://ollama.com/

## Ollamaにモデル登録
Ollamaを実行するにはPowerShellなどでコマンドを打つ必要があります。

``` PowerShell
ollama run <model>

```

CLIについて詳しくは[こちら](https://zenn.dev/buenotheebiten/articles/7c351b06494be0)を参考にしてください。

今回はOllamaで既にダウンロードしたggufモデルを読み込んで実行します。ここからの手順は以下のページを参考にして下し。

https://note.com/cppp_cpchan/n/n92c7795f5939

ggufファイルと同じフォルダにモデルの定義となるモデルファイル(今回は`.model`)を作成しました。

``` PowerShell
ollama create DeepSeek-R1-Distill-Qwen-14B-Japanese-Q4_K_M -f DeepSeek-R1-Distill-Qwen-14B-Japanese-Q4_K_M.model
```

ollamaでモデルを作成します。`-f`でモデルファイルを指定し実行します。成功すると以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604944/7f01bd40-0c60-d2b6-671e-01faef3efcbd.png)
※上記画像ではファイル名をミスっています。今回ダウンロードした.ggufファイルとしたいので、正確には**Japaneseを付けたもの**です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604944/738027a3-5d39-3e5c-7472-1f9ab7caf362.png)


実行前は`ollama list`に何もありませんでしたが、実行後は作成したモデルが追加されています。

PowerShellで`ollama serve`（serverではない！）を実行しサーバーを起動しておきます。

:::note warn
```
Error: listen tcp 127.0.0.1:11434: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.
```
となった場合は、右下のollamaアイコンを右クリックしOllamaを停止してください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604944/6f094444-f93d-c06d-16fa-09b9bb2253b4.png)
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604944/68f5415a-771c-5119-7e42-08c3cace795f.png)

## VSCodeの設定
今回はVSCodeからClineを使用するので、拡張機能をインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604944/a2794acf-4ee8-25be-3324-0064ce64a629.png)


インストールするとVSCode画面左にClineのアイコンが出るので選択し設定を進めます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604944/449b4fe5-2ba7-b62d-451a-599d697fd852.png)

ここでAPIプロバイダーを選択しOpenAIを選択し、APIキーを入力...するのではなく、今回はOllamaを選択しローカルに立てたサーバーおよびモデルIDを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604944/284576bb-5cab-e316-3c50-c6d1acd64e31.png)

## 実行
Clineに以下の内容を指示してみました。

「現在のフォルダにCline.goファイルを作成します。
時刻時の日付と曜日を出力するコードを書き、保存してください」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604944/27e77292-9114-d390-a9bc-e8f28deb8a9c.png)

実行コマンドまで教えてくれるとは、Cline便利だな。。。
生成コードの精度もほぼほぼ申し分なし！

まあ、`fmt.Printf("曜日: %A\n", now.Weekday())`のコード、`％A`じゃなくて`%s`じゃないかな？？

``` PowerShell
日付: 2025-02-04
時刻: 11:58PM
曜日: %!A(time.Weekday=2)
```