o1-mini相当の性能を持つDeepSeek-r1:32bをroo codeで快適なAIコーディング環境を構築してみる
ジーニーのCTO、孟です。
先日、vLLMを使用したDeepSeek-R1の動作記事を書きましたが、vLLMは速度が速い一方で、個人用途におけるメモリ使用率に関してはOllamaの方が適していると感じました。
そこで今回は、ローカル環境で32BサイズのDeepSeek-R1モデルを動かす方法について、記事として共有したいと思います。
DeepSeekの公式APIを使用する場合、オプトアウトが明記されていないとデータの安全性に懸念が生じるため、DeepSeek-r1をローカル環境で構築することでデータを海外に送ることなく、セキュアな環境を整えることを目的としています。弊社ジーニーではお客様のデータを多く扱っておりますので、セキュリティ面を常に意識してプロダクトを開発しております。
※新卒入社時には「安全なWebアプリケーションの作り方」という本を全員に配布し、ブートキャンプで使用しています。これにより、新入社員がセキュアな開発手法を習得し、プロダクトの安全性を高めることを目的としています。
では早速、 まずはOllamaのインストールから始めましょう。 https://ollama.com/
次に、ご自身のグラフィックボード環境に合わせてモデルサイズを選んでください。
私の場合、4090の24GBメモリを搭載しているため、最大32Bのモデルが使用可能なので、それを選びました。
次に、モデルをダウンロードして動かしましょう。(cyberagentさんの日本語データで追加学習を行ったLLMを利用させていただきます。ありがとうございます!bluepen5805さんのgguf版もありがとうございます!)
ollama run hf.co/bluepen5805/DeepSeek-R1-Distill-Qwen-32B-Japanese-gguf:Q4_K_M
たったこれだけです。
それでは、実際にチャットしてみましょう。
>>> 日本国内で最も高い山はなに?
<think>
ユーザーが「日本国内で最も高い山はなに?」と質問しています。まず、これは地理に関する基本的な知識を尋ねるものです。正確な答えを提供する必要があり
ます。
日本の最高峰である富士山(3,776メートル)が一般的に知られていますが、確認が必要です。最近の地図や地理学の定義で変更がないかチェックします。また、
海外ではアルプスなどの高い山がありますが、日本国内に限定するので問題ありません。
さらに、ユーザーが子供なのか、大人なのか、教育目的なのかを推測し、回答の深さを調整します。ここではシンプルな事実を答えることが求められています。
必要に応じて補足情報を加えます。例えば、富士山の特徴や観光情報などですが、質問が「最も高い山」のみなので、核心に絞って回答します。
誤解を防ぐため、計測方法(雪頂までの高さなのか基準面からの高さか)について触れる必要があるかもしれません。しかし、一般的な認識では富士山を最高峰
と捉えているので、その点も確認しておきます。
最終的には、正確で簡潔な回答を心掛けます。
</think>
日本国内で最も高い山は **富士山(ふじさん)** です。
標高は **3,776メートル**(2021年現在の測定値・基準面から計測)とされ、静岡県と山梨県にまたがるこの活火山は、日本を代表する観光地としても知られています。
### 補足情報
- **富士山の特徴**
- 絶滅した火山で、現在も地震や微小な噴気活動が確認される「休火山」に分類されています。
- 世界文化遺産(2013年登録)として、登山客だけでなく文人墨客からも愛される存在です。
- **標高測定の注意点**
富士山は雪頂部分が変動するため、正確な「現在の最高峰」は毎年測量され調整されます。例えば2019年に「3,776.24m」と発表された際には話題になりました。
- **日本第二位以降の山**
2位:八ヶ岳連峰(3,202m)
3位:北岳(3,193m)
(※いずれも甲斐駒ヶ岳を含む富士山群とは別の山脈です)
このように、富士山は単なる「高い山」ではなく、日本文化や自然環境に深い影響を与える存在と言えます
さすがCAさん、とても良い結果を返してくれましたね!速さも実用的なレベルで、遅さを感じませんね。
nvidia-smiを叩いてみた結果がこちら:
Wed Jan 29 00:04:59 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 550.144.03 Driver Version: 550.144.03 CUDA Version: 12.4 |
|-----------------------------------------+------------------------+----------------------+
| 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 4090 Off | 00000000:06:00.0 Off | Off |
| 30% 50C P2 290W / 450W | 21877MiB / 24564MiB | 91% Default |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| 0 N/A N/A 2354 G /usr/lib/xorg/Xorg 67MiB |
| 0 N/A N/A 3048 G /usr/bin/gnome-shell 60MiB |
| 0 N/A N/A 878013 C ...rs/cuda_v12_avx/ollama_llama_server 21732MiB |
+-----------------------------------------------------------------------------------------+
まずpython clientで叩いて見ましょう
(ping pongで返せるpythonのapi serverのサンプルコードをくれ)で指示してみる
from openai import OpenAI
client = OpenAI(
base_url = 'http://localhost:11434/v1',
api_key='ollama',
)
response = client.chat.completions.create(
model="hf.co/bluepen5805/DeepSeek-R1-Distill-Qwen-32B-Japanese-gguf:Q4_K_M",
messages=[
{"role": "system", "content": "You are an Engineer."},
{"role": "user", "content": "give me an api server sample code use python, and write a ping pong endpoint"}
]
)
print(response.choices[0].message.content)
結果も悪くない(think部分を割愛):
from flask import Flask, jsonify
import logging
# Create a logger
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
app = Flask(__name__)
app.config['OPENAPI_SWAGGER_UI_PATH'] = '/swagger-ui'
app.config['OPENAPI_SWAGGER_UI_URL'] = 'https://cdn.jsdelivr.net/npm/swagger-ui-dist/'
@app.route('/ping', methods=['GET'])
def ping():
logger.info("Received a ping request")
return jsonify({'pong': True})
# Optional: Add basic API documentation using OpenAPI
openapi_spec = {
"info": {
"title": "Ping Pong API",
"version": "1.0"
},
"paths": {
"/ping": {
"get": {
"summary": "Ping Pong endpoint",
"description": "Returns 'pong' when /ping is requested.",
"responses": {
"200": {
"description": "Successful response",
"content": {
"application/json": {
"example": {"pong": True}
}
}
}
},
"tags": ["Ping"]
}
}
}
}
@app.route('/')
def home():
return "Welcome to Ping Pong API!"
if __name__ == '__main__':
app.run(debug=True)
ドキュメントまで書いてくれるのが想定外でした、とても良いと思います。
※実際の出力に、think部分と上記のサンプルコードを動かす手順を書いてくれましたが、記事にすると長すぎるため省略させていただきます。
よし、VSCode + RooCode(旧Roo Cline)を設定して使えるようにしてみましょう。(どんどん欲張りですねw。CursorではOllamaとの相性が良くないため、今回はトレンドのRooCodeで検証します)
同じPC上で実行する場合は、以下の手順を省略しても問題ありません。ただし、GPUサーバーを別のPCで構築している場合は、先ほどのコマンドでサーバーを起動しておきましょう。他のPCからアクセス可能になります。
# 環境変数を設定(ポート番号は自由に変更してください)
echo "export OLLAMA_HOST=0.0.0.0:5050" >> ~/.bashrc
source ~/.bashrc
# serveコマンドを先に実行する必要があります
ollama serve
ollama run hf.co/bluepen5805/DeepSeek-R1-Distill-Qwen-32B-Japanese-gguf:Q4_K_M
RooCodeの設定は以下の通りです:(apikeyは適当でおk)
完成です!これでセキュアなAIコーディング環境の構築が完了しましたね。(公式のDeepSeek APIを利用すると、どうしてもソースコードが学習されないかという不安が拭いきれません。)
Roo codeとは?
※補足:弊社ジーニーでも積極的にAIコーディングを導入しており、PoCの結果、生産性がN倍以上向上したとのフィードバックをいただいています。これまで数ヶ月かかっていたプロダクト開発の工程が、ツールを活用することで大幅に短縮されることがよくあります。
このような記事を今後もどんどん発信して行きたいと思います。
AIをゴリゴリ使ってプロダクトを一緒に開発していきたい方、是非弊社にjoinして頂けると嬉しいです!
Discussion