🚀

ds4/DeepSeek V4 Flash を macOS にセットアップし常駐化

に公開

この記事の目的

この記事では、備忘も兼ねてmacOS 上で DwarfStar 4 / DS4 を使い、DeepSeek V4 Flash をローカル推論サーバーとして動かす手順をまとめます。

最終的なゴールは次の状態です。

  • DS4 本体を $HOME/llm/ds4 に配置する
  • DS4 をビルドする
  • ./download_model.sh q2-imatrix で DeepSeek V4 Flash の GGUF モデルを取得する
  • ds4flash.gguf が正しく参照されていることを確認する
  • ds4-serverhttp://127.0.0.1:8000/v1 で起動する
  • Hermes Agent から DS4 をバックエンドモデルとして使う
  • macOS の LaunchAgent を使って、DS4 をターミナル常駐なしでバックグラウンド起動する
  • ログイン時に自動起動し、落ちた場合も自動再起動する

前提環境

この記事では、以下の環境を前提にしています。

OS: macOS
ユーザー名: kamo
DS4配置先: $HOME/llm/ds4
モデル: DeepSeek V4 Flash
量子化: q2-imatrix
DS4モデル参照名: $HOME/llm/ds4/ds4flash.gguf
DS4サーバーポート: 8000
Context length: 300000
KV cache directory: $HOME/Library/Caches/ds4-kv
KV cache disk size: 131072 MB = 128 GB
LaunchAgent label: com.kamo.ds4

DS4とは何か

DS4 / DwarfStar 4 は、DeepSeek V4 Flash をローカル環境で動かすための推論エンジンです。ローカル/個人マシン向けには llama.cpp や Ollama、LM Studio、サーバ向けには vLLM などが代表的ですが、それらとは違い DS4 は DeepSeek V4 Flash に強く特化しているのが特徴です。

重要なのは、DS4はモデル名ではなく、DeepSeek V4 Flashを動かすためのランナー兼APIサーバーであるという点です。

DS4を使うと、ローカルMac上で次のようなAPIサーバーを立てられます。

http://127.0.0.1:8000/v1

このAPIは OpenAI 互換風のエンドポイントを持っているため、Hermes Agent のようなAIエージェントのバックエンドとして利用できます。


全体構成

今回作る構成は次のようになります。

Hermes Agent

OpenAI互換API

http://127.0.0.1:8000/v1

ds4-server

ds4flash.gguf

DeepSeek V4 Flash GGUF

さらに、ds4-server は macOS の LaunchAgent で管理します。

macOS launchd / LaunchAgent

$HOME/bin/start-ds4-server

$HOME/llm/ds4/ds4-server

なぜターミナル常駐ではなくLaunchAgent化するのか

最初は次のように、ターミナルで直接起動できます。

cd $HOME/llm/ds4

./ds4-server \
  --ctx 300000 \
  --kv-disk-dir $HOME/Library/Caches/ds4-kv \
  --kv-disk-space-mb 131072 \
  --port 8000

この方法でも動きますが、常用には次の問題があります。

  • ターミナルを閉じると停止する
  • macOS再ログイン後に手動起動が必要
  • 落ちた場合に自動復旧しない
  • ログ管理がやや面倒
  • Hermesや他のエージェントから常時使うには不便

そこで、macOS標準の launchd / LaunchAgent を使って、DS4を常駐サービス化します。


1. 事前準備

1.1 Xcode Command Line Toolsを確認する

DS4はローカルでビルドするため、macOSの開発ツールが必要です。

まず、Command Line Tools が入っているか確認します。

xcode-select -p

次のようなパスが表示されればOKです。

/Library/Developer/CommandLineTools

未インストールの場合は、次でインストールします。

xcode-select --install

インストール後、もう一度確認します。

xcode-select -p

1.2 作業ディレクトリを作る

今回は DS4 を次の場所に置きます。

$HOME/llm/ds4

まず親ディレクトリを作ります。

mkdir -p $HOME/llm
cd $HOME/llm

2. DS4本体を取得する

GitHubから DS4 を取得します。

cd $HOME/llm

git clone https://github.com/antirez/ds4.git ds4
cd $HOME/llm/ds4

取得できたか確認します。

pwd
ls -la

README.mdMakefiledownload_model.sh などが見えればOKです。

ls -l Makefile download_model.sh

3. DS4をビルドする

DS4ディレクトリで make します。

cd $HOME/llm/ds4
make

完了後、実行ファイルを確認します。

ls -l ds4 ds4-server

期待する状態は、少なくとも次の2つが存在することです。

ds4
ds4-server

もし実行権限がなければ付与します。

chmod +x $HOME/llm/ds4/ds4
chmod +x $HOME/llm/ds4/ds4-server

4. モデルをダウンロードする

4.1 128GB Macでは q2-imatrix を選ぶ

128GB RAM の Mac では、まず q2-imatrix を使うのが現実的です。

DS4ディレクトリで次を実行します。

cd $HOME/llm/ds4

./download_model.sh q2-imatrix

このスクリプトが DeepSeek V4 Flash のGGUFモデルをダウンロードし、DS4が参照する ds4flash.gguf を用意します。

重要な点として、通常はこのスクリプトを使えば、自分で ln -s してシンボリックリンクを貼る必要はありません。

download_model.sh 実行後に、次を確認します。

cd $HOME/llm/ds4
ls -l ds4flash.gguf
readlink ds4flash.gguf || true

ds4flash.gguf が存在していればOKです。

シンボリックリンクの場合は、次のような表示になります。

ds4flash.gguf -> gguf/DeepSeek-V4-Flash-....gguf

実ファイルとして配置されている場合も、DS4が参照できれば問題ありません。

モデルファイルの容量確認は次です。

du -sh $HOME/llm/ds4/gguf 2>/dev/null || true
du -sh $HOME/llm/ds4/ds4flash.gguf 2>/dev/null || true

4.2 ダウンロードが途中で失敗した場合

ネットワーク切断やディスク容量不足で失敗した場合は、まず空き容量を確認します。

df -h $HOME/llm

再度同じコマンドを実行します。

cd $HOME/llm/ds4
./download_model.sh q2-imatrix

途中までダウンロード済みの場合、スクリプト側で再開または再取得されることがあります。


5. DS4を単体CLIで動作確認する

サーバー化する前に、まずCLIとして動くか確認します。

cd $HOME/llm/ds4

./ds4 -p "日本語で、DeepSeek V4 FlashとDS4の関係を3行で説明して。"

応答が返れば、モデルの読み込みと推論は成功しています。

もしここでモデルファイルが見つからないエラーが出る場合は、次を確認します。

cd $HOME/llm/ds4
ls -l ds4flash.gguf
readlink ds4flash.gguf || true

6. DS4サーバーを手動起動して確認する

LaunchAgent化する前に、まずは手動で ds4-server を起動して動作確認します。

cd $HOME/llm/ds4

mkdir -p $HOME/Library/Caches/ds4-kv

./ds4-server \
  --ctx 300000 \
  --kv-disk-dir $HOME/Library/Caches/ds4-kv \
  --kv-disk-space-mb 131072 \
  --port 8000

このターミナルは起動したままにします。

別ターミナルを開き、APIが応答するか確認します。

curl http://127.0.0.1:8000/v1/models

正常なら、次のようなJSONが返ります。

{
  "object": "list",
  "data": [
    {
      "id": "deepseek-v4-flash",
      "object": "model",
      "owned_by": "ds4.c",
      "name": "DeepSeek V4 Flash",
      "context_length": 300000
    }
  ]
}

実際には supported_parameters など、より多くの項目が返る場合があります。


6.1 Chat Completions APIを確認する

Hermesなどのエージェントから使う前に、簡単なAPIリクエストも確認しておくと安心です。

curl http://127.0.0.1:8000/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "deepseek-v4-flash",
    "messages": [
      {"role": "user", "content": "日本語で短く自己紹介して。"}
    ],
    "stream": false
  }'

応答本文に文章が含まれていればOKです。


7. 300k contextにしている理由

DS4 / DeepSeek V4 Flash は大きなコンテキスト長に対応できますが、常用では最大値を常に使う必要はありません。

今回の運用では、速度と長文処理能力のバランスを取って 300000 にしています。

目安は次の通りです。

context length 用途
100000 軽い調査、通常チャット、速度重視
300000 Hermes運用、長文調査、実用バランス重視
500000 大きめのログ・リポジトリ解析
1000000 最大コンテキスト重視。ただし遅くなりやすい

Hermes側の設定とDS4サーバー側の --ctx は揃えるのが基本です。


8. KV Disk Cacheについて

起動オプションの中で重要なのが、次の2つです。

--kv-disk-dir $HOME/Library/Caches/ds4-kv
--kv-disk-space-mb 131072

8.1 KV cacheとは

LLMは長いプロンプトを処理するとき、過去のトークンの計算結果を内部に保持します。これをKV cacheと呼びます。

HermesやClaude CodeのようなAIエージェントは、毎回長いsystem prompt、ツール定義、会話履歴、ファイル内容などを送ります。

DS4のDisk KV Cacheを有効にしておくと、長いprefixを再利用しやすくなり、再開時や同じようなリクエストの処理が効率化されます。

8.2 推奨容量

今回のように300k contextで運用するなら、64GBでも動きますが、ディスクに余裕があるなら128GBを確保しておくと安心です。

用途 --kv-disk-space-mb 容量
軽い検証 16384 16GB
通常利用 32768 32GB
300k context 常用 65536 64GB
Hermes / Codex / Claude Code併用 131072 128GB
複数プロジェクト・長期運用 262144 256GB

今回の設定は次です。

--kv-disk-space-mb 131072

これは128GBです。

KV cacheの使用量を確認するには、次のコマンドを使います。

du -sh $HOME/Library/Caches/ds4-kv

キャッシュを削除したい場合は、DS4を停止してから次を実行します。

rm -rf $HOME/Library/Caches/ds4-kv/*

9. Hermesのモデル設定

Hermes Agent から DS4を使うには、Hermesの config.yamlmodel: セクションをDS4用に変更します。

設定ファイルの場所を確認します。

hermes config path

今回の環境では次のパスです。

$HOME/.hermes/config.yaml

設定全体を表示します。

hermes config show

編集します。

hermes config edit

または、直接エディタで開きます。

nano $HOME/.hermes/config.yaml

9.1 modelセクションの設定

既存の model: セクションがある場合、末尾にもう1つ model: を追記してはいけません

YAMLでは同じトップレベルキーを複数書くと、後勝ちになったり、ツール側の解釈が不安定になったりします。

model: はトップレベルに1つだけにします。

DS4用の設定は次です。model: セクションでアクティブなモデルを指定し、providers: セクションにDS4をプロバイダとして登録します。

model:
    provider: ds4-launch
    default: deepseek-v4-flash
    base_url: http://127.0.0.1:8000/v1
    api_key: ds4
    context_length: 300000

providers:
    ds4-launch:
        api: http://127.0.0.1:8000/v1
        default_model: deepseek-v4-flash
        models:
            - deepseek-v4-flash
        name: DS4

既存がOllama設定の場合は、たとえば次のような設定を置き換えます。

model:
    api_key: ollama
    base_url: http://127.0.0.1:11434/v1
    default: qwen3.6:35b-a3b-q8_0
    provider: ollama-launch

上記をDS4用に置き換えます。


9.2 terminalセクションについて

既に terminal: セクションがある場合は、これも追記しません。

既存の terminal: はそのまま残します。たとえば以下のような内容はそのままでOKです。

terminal:
    auto_source_bashrc: true
    backend: local
    container_cpu: 1
    container_disk: 51200
    container_memory: 5120
    container_persistent: true
    cwd: .
    daytona_image: nikolaik/python-nodejs:python3.11-nodejs20
    docker_env: {}
    docker_extra_args: []
    docker_forward_env: []
    docker_image: nikolaik/python-nodejs:python3.11-nodejs20
    docker_mount_cwd_to_workspace: false
    docker_run_as_host_user: false
    docker_volumes: []
    env_passthrough: []
    lifetime_seconds: 300
    modal_image: nikolaik/python-nodejs:python3.11-nodejs20
    modal_mode: auto
    persistent_shell: true
    shell_init_files: []
    singularity_image: docker://nikolaik/python-nodejs:python3.11-nodejs20
    timeout: 180
    vercel_runtime: node24

terminal.backend: local であれば、Hermesはローカルターミナルを使います。


9.3 Hermes設定確認

設定後、次のコマンドで確認します。

hermes config show

期待される表示例です。

◆ Model
  Model:        {'provider': 'ds4-launch', 'default': 'deepseek-v4-flash', 'base_url': 'http://127.0.0.1:8000/v1', 'api_key': 'ds4', 'context_length': 300000}

設定ファイルとして壊れていないか確認します。

hermes config check

model: が複数ないか確認します。

grep -n '^model:' $HOME/.hermes/config.yaml

terminal: も複数ないか確認します。

grep -n '^terminal:' $HOME/.hermes/config.yaml

それぞれ1行だけ出ればOKです。


10. HermesからDS4を使う

DS4サーバーが起動している状態で、Hermesを起動します。

hermes

プロジェクトディレクトリで使う場合は、対象ディレクトリに移動してから起動します。

cd /path/to/your/project
hermes

Hermes内で、まず次のように聞くと接続確認になります。

現在接続しているモデル名と、コンテキスト長を教えてください。

DS4側でAPI確認するには、別ターミナルで次を実行します。

curl http://127.0.0.1:8000/v1/models

11. DS4をLaunchAgentで常駐化する

手動起動で問題なく動くことを確認できたら、次にLaunchAgent化します。

LaunchAgent化すると、ターミナルを開きっぱなしにしなくてもDS4がバックグラウンドで動きます。


11.1 起動スクリプトを作成する

まず、DS4起動用のスクリプトを作ります。

mkdir -p $HOME/bin
mkdir -p $HOME/Library/Caches/ds4-kv
mkdir -p $HOME/Library/Logs

cat > $HOME/bin/start-ds4-server <<SCRIPT_EOF
#!/bin/zsh
set -e

cd $HOME/llm/ds4

exec $HOME/llm/ds4/ds4-server \
  --ctx 300000 \
  --kv-disk-dir $HOME/Library/Caches/ds4-kv \
  --kv-disk-space-mb 131072 \
  --port 8000
SCRIPT_EOF

chmod +x $HOME/bin/start-ds4-server

確認します。

ls -l $HOME/bin/start-ds4-server
cat $HOME/bin/start-ds4-server

ポイントは exec を使っていることです。

launchd で管理する場合、スクリプトが別プロセスを起動してすぐ終了するより、最後に exec で本体プロセスに置き換わる方が扱いやすいです。


11.2 LaunchAgent plistを作成する

LaunchAgentの設定ファイルを作ります。

mkdir -p $HOME/Library/LaunchAgents

cat > $HOME/Library/LaunchAgents/com.kamo.ds4.plist <<PLIST_EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
 "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>com.kamo.ds4</string>

    <key>ProgramArguments</key>
    <array>
      <string>$HOME/bin/start-ds4-server</string>
    </array>

    <key>WorkingDirectory</key>
    <string>$HOME/llm/ds4</string>

    <key>RunAtLoad</key>
    <true/>

    <key>KeepAlive</key>
    <true/>

    <key>ThrottleInterval</key>
    <integer>10</integer>

    <key>StandardOutPath</key>
    <string>$HOME/Library/Logs/ds4-server.out.log</string>

    <key>StandardErrorPath</key>
    <string>$HOME/Library/Logs/ds4-server.err.log</string>
  </dict>
</plist>
PLIST_EOF

chmod 600 $HOME/Library/LaunchAgents/com.kamo.ds4.plist

11.3 plistの中身の意味

主な設定の意味は次の通りです。

項目 意味
Label LaunchAgentの名前。ここでは com.kamo.ds4
ProgramArguments 実行するコマンド。今回は起動スクリプト
WorkingDirectory DS4の作業ディレクトリ
RunAtLoad 登録時・ログイン時に自動起動する
KeepAlive プロセスが落ちたら再起動する
ThrottleInterval 再起動の連打を防ぐ間隔
StandardOutPath 標準出力ログ
StandardErrorPath 標準エラーログ

12. LaunchAgentを登録して起動する

次のコマンドでLaunchAgentを登録します。

launchctl bootstrap gui/$(id -u) $HOME/Library/LaunchAgents/com.kamo.ds4.plist
launchctl enable gui/$(id -u)/com.kamo.ds4
launchctl kickstart -k gui/$(id -u)/com.kamo.ds4

それぞれの意味です。

コマンド 意味
bootstrap LaunchAgentをlaunchdに登録する
enable 起動可能状態にする
kickstart -k 既存プロセスがあれば止めて起動し直す

13. LaunchAgentの状態確認

状態確認します。

launchctl print gui/$(id -u)/com.kamo.ds4 | head -80

正常なら、次のような表示が含まれます。

state = running
program = $HOME/bin/start-ds4-server
working directory = $HOME/llm/ds4
stdout path = $HOME/Library/Logs/ds4-server.out.log
stderr path = $HOME/Library/Logs/ds4-server.err.log

プロセスも確認します。

ps aux | grep '[d]s4-server'

正常なら、次のようなプロセスが見えます。

$HOME/llm/ds4/ds4-server --ctx 300000 --kv-disk-dir $HOME/Library/Caches/ds4-kv --kv-disk-space-mb 131072 --port 8000

APIも確認します。

curl http://127.0.0.1:8000/v1/models

正常な実例です。

{
  "object": "list",
  "data": [
    {
      "id": "deepseek-v4-flash",
      "object": "model",
      "created": 1767225600,
      "owned_by": "ds4.c",
      "name": "DeepSeek V4 Flash",
      "context_length": 300000,
      "top_provider": {
        "context_length": 300000,
        "max_completion_tokens": 300000,
        "is_moderated": false
      },
      "supported_parameters": [
        "tools",
        "tool_choice",
        "max_tokens",
        "temperature",
        "top_p",
        "top_k",
        "min_p",
        "stop",
        "seed",
        "stream",
        "reasoning_effort"
      ]
    }
  ]
}

この応答が返れば、DS4サーバーは正常に動いています。


14. ログ確認

標準出力ログを確認します。

tail -n 100 $HOME/Library/Logs/ds4-server.out.log

リアルタイムで見る場合は次です。

tail -f $HOME/Library/Logs/ds4-server.out.log

エラーログは次です。

tail -n 100 $HOME/Library/Logs/ds4-server.err.log

リアルタイムで見る場合は次です。

tail -f $HOME/Library/Logs/ds4-server.err.log

ログに何も出ていなくても、curl http://127.0.0.1:8000/v1/models が正常なら問題ありません。


14.1 ターミナル起動時のコンソール表示がログに出ない場合

StandardOutPath / StandardErrorPath は、標準出力と標準エラーに出た内容だけを記録します。

ターミナルで直接起動したときの表示の一部が、LaunchAgentのログに記録されない場合があります。これは、プログラム側がTTY接続時だけ表示する情報や、疑似ターミナル向けの表示を使っている場合に起こります。

ターミナル起動時に近いコンソール表示も保存したい場合は、script コマンドで疑似TTYを作って起動します。

$HOME/bin/start-ds4-server を次のように変更します。

cat > $HOME/bin/start-ds4-server <<SCRIPT_EOF
#!/bin/zsh
set -e

mkdir -p $HOME/Library/Caches/ds4-kv
mkdir -p $HOME/Library/Logs

exec /usr/bin/script -a -q $HOME/Library/Logs/ds4-server.console.log /bin/zsh -lc '
cd $HOME/llm/ds4

exec $HOME/llm/ds4/ds4-server \
  --ctx 300000 \
  --kv-disk-dir $HOME/Library/Caches/ds4-kv \
  --kv-disk-space-mb 131072 \
  --port 8000
'
SCRIPT_EOF

chmod +x $HOME/bin/start-ds4-server

LaunchAgentを再起動します。

launchctl kickstart -k gui/$(id -u)/com.kamo.ds4

ログを確認します。

tail -f $HOME/Library/Logs/ds4-server.console.log

注意点として、script を使ったログにはANSI制御文字やカーソル制御文字が混じることがあります。表示が見づらい場合は、通常の out.log / err.log と使い分けるのが良いです。


15. よく使う運用コマンド

状態確認

launchctl print gui/$(id -u)/com.kamo.ds4 | head -80

プロセス確認

ps aux | grep '[d]s4-server'

API確認

curl http://127.0.0.1:8000/v1/models

再起動

launchctl kickstart -k gui/$(id -u)/com.kamo.ds4

停止

launchctl bootout gui/$(id -u) $HOME/Library/LaunchAgents/com.kamo.ds4.plist

再登録

launchctl bootstrap gui/$(id -u) $HOME/Library/LaunchAgents/com.kamo.ds4.plist
launchctl kickstart -k gui/$(id -u)/com.kamo.ds4

完全削除

launchctl bootout gui/$(id -u) $HOME/Library/LaunchAgents/com.kamo.ds4.plist
rm $HOME/Library/LaunchAgents/com.kamo.ds4.plist

16. launchctl print の表示例と見方

実際の確認例です。

gui/501/com.kamo.ds4 = {
    active count = 1
    path = $HOME/Library/LaunchAgents/com.kamo.ds4.plist
    type = LaunchAgent
    state = running

    program = $HOME/bin/start-ds4-server
    working directory = $HOME/llm/ds4

    stdout path = $HOME/Library/Logs/ds4-server.out.log
    stderr path = $HOME/Library/Logs/ds4-server.err.log

    properties = keepalive | runatload | inferred program
}

重要なのは次です。

表示 意味
state = running 起動中
type = LaunchAgent ユーザー単位の常駐プロセス
program = $HOME/bin/start-ds4-server 起動スクリプトが使われている
`properties = keepalive runatload`

次のような表示があっても、再起動操作後なら問題ないことが多いです。

last terminating signal = Terminated: 15
runs = 2

これは kickstart -kbootout によって一度プロセスを停止した履歴である可能性があります。


17. context lengthを変更したい場合

たとえば、300kから500kに変更したい場合は、2か所を揃えます。

  1. DS4サーバーの --ctx
  2. Hermesの model.context_length

17.1 DS4側

起動スクリプトを編集します。

nano $HOME/bin/start-ds4-server

次の行を変更します。

--ctx 300000

500kにするなら次です。

--ctx 500000

17.2 Hermes側

hermes config set model.context_length 500000

確認します。

hermes config show

17.3 DS4を再起動

launchctl kickstart -k gui/$(id -u)/com.kamo.ds4

API確認します。

curl http://127.0.0.1:8000/v1/models

context_length が変更後の値になっていればOKです。


18. 特殊ケース: DS4ディレクトリを移動した場合のシンボリックリンク張り替え

この章は通常のセットアップ手順ではありません。

./download_model.sh q2-imatrix でモデルをダウンロードした場合、通常は ds4flash.gguf が用意されるため、自分でシンボリックリンクを貼る必要はありません。

ここで扱うのは、次のような特殊ケースです。

  • 以前は $HOME/dev/ds4 にDS4を置いていた
  • 途中で $HOME/llm/ds4 にディレクトリを移動した
  • その結果、ds4flash.gguf が古いパスを指している
  • モデルファイル自体は新しい場所にある

このような場合だけ、リンクを張り替えます。

確認します。

cd $HOME/llm/ds4
ls -l ds4flash.gguf
readlink ds4flash.gguf || true

もし次のように古いパスを指している場合は修正します。

ds4flash.gguf -> $HOME/dev/ds4/gguf/DeepSeek-V4-Flash-IQ2XXS-w2Q2K-AProjQ8-SExpQ8-OutQ8-chat-v2-imatrix.gguf

新しい場所に張り替えるコマンドです。

cd $HOME/llm/ds4

ln -sfn \
  $HOME/llm/ds4/gguf/DeepSeek-V4-Flash-IQ2XXS-w2Q2K-AProjQ8-SExpQ8-OutQ8-chat-v2-imatrix.gguf \
  ds4flash.gguf

確認します。

ls -l ds4flash.gguf
readlink ds4flash.gguf

期待される表示です。

ds4flash.gguf -> $HOME/llm/ds4/gguf/DeepSeek-V4-Flash-IQ2XXS-w2Q2K-AProjQ8-SExpQ8-OutQ8-chat-v2-imatrix.gguf

繰り返しますが、通常セットアップではこの作業は不要です。download_model.sh を使った通常フローでは、まずはリンクを手動で触らず、そのまま ./ds4./ds4-server の動作確認に進みます。


19. DS4が起動しない場合の確認ポイント

19.1 plistが登録されているか

launchctl print gui/$(id -u)/com.kamo.ds4 | head -80

19.2 ds4-serverのパスが正しいか

ls -l $HOME/llm/ds4/ds4-server

19.3 起動スクリプトに実行権限があるか

ls -l $HOME/bin/start-ds4-server

実行権限がなければ付与します。

chmod +x $HOME/bin/start-ds4-server

19.4 モデル参照が正しいか

cd $HOME/llm/ds4
ls -l ds4flash.gguf
readlink ds4flash.gguf || true

ds4flash.gguf が存在しない場合は、まず通常フローとしてモデルダウンロードをやり直します。

cd $HOME/llm/ds4
./download_model.sh q2-imatrix

ディレクトリ移動などの特殊事情がある場合だけ、前章のシンボリックリンク張り替えを検討します。

19.5 ポート8000が既に使われていないか

lsof -i :8000

既に別のプロセスが使っている場合は、そのプロセスを止めるか、DS4のポートを変更します。

19.6 エラーログを見る

tail -n 200 $HOME/Library/Logs/ds4-server.err.log

20. HermesがDS4を使ってくれない場合

20.1 Hermesの設定確認

hermes config show

Model が次のようになっているか確認します。

provider: ds4-launch
base_url: http://127.0.0.1:8000/v1
default: deepseek-v4-flash
context_length: 300000

20.2 model: が複数ないか確認

grep -n '^model:' $HOME/.hermes/config.yaml

複数出る場合は、1つだけに整理します。

20.3 DS4サーバーが生きているか確認

curl http://127.0.0.1:8000/v1/models

20.4 Hermesを再起動する

設定変更後、既存のHermesセッションには反映されない場合があります。

Hermesを終了して、再起動します。

hermes

21. セキュリティ上の注意

今回の設定では、DS4は次のURLで待ち受けます。

http://127.0.0.1:8000/v1

127.0.0.1 はローカルホストです。つまり、基本的には同じMac上からだけアクセスできます。

外部PCからアクセスさせたい場合は、別途ネットワーク公開設定が必要になりますが、初期運用ではおすすめしません。

理由は次の通りです。

  • APIキーが実質的にローカル用の簡易値である
  • LLMサーバーを外部公開すると不正利用される危険がある
  • 自動エージェントと組み合わせる場合、意図しない操作につながる可能性がある

まずは 127.0.0.1 のローカル限定運用が安全です。


22. 現在の完成形

今回の最終構成は次です。

22.1 DS4配置先

$HOME/llm/ds4

22.2 モデルダウンロード

cd $HOME/llm/ds4
./download_model.sh q2-imatrix

通常はこのスクリプトにより ds4flash.gguf が用意されるため、シンボリックリンクを手動で作る必要はありません。

22.3 DS4サーバー

$HOME/llm/ds4/ds4-server \
  --ctx 300000 \
  --kv-disk-dir $HOME/Library/Caches/ds4-kv \
  --kv-disk-space-mb 131072 \
  --port 8000

22.4 API endpoint

http://127.0.0.1:8000/v1

22.5 モデル名

deepseek-v4-flash

22.6 Hermes設定

model:
    provider: ds4-launch
    default: deepseek-v4-flash
    base_url: http://127.0.0.1:8000/v1
    api_key: ds4
    context_length: 300000

providers:
    ds4-launch:
        api: http://127.0.0.1:8000/v1
        default_model: deepseek-v4-flash
        models:
            - deepseek-v4-flash
        name: DS4

22.7 LaunchAgent

$HOME/Library/LaunchAgents/com.kamo.ds4.plist

22.8 起動スクリプト

$HOME/bin/start-ds4-server

22.9 ログ

$HOME/Library/Logs/ds4-server.out.log
$HOME/Library/Logs/ds4-server.err.log

疑似TTYログを有効化した場合は、追加で次も使います。

$HOME/Library/Logs/ds4-server.console.log

23. 最小チートシート

最後に、よく使うコマンドだけまとめます。

# DS4本体取得
mkdir -p $HOME/llm
cd $HOME/llm
git clone https://github.com/antirez/ds4.git ds4
cd $HOME/llm/ds4

# ビルド
make

# モデルダウンロード。通常はこれでds4flash.ggufも用意される
./download_model.sh q2-imatrix

# CLI単体確認
./ds4 -p "日本語でDS4について3行で説明して。"

# 手動サーバー起動
./ds4-server \
  --ctx 300000 \
  --kv-disk-dir $HOME/Library/Caches/ds4-kv \
  --kv-disk-space-mb 131072 \
  --port 8000

# DS4 API確認
curl http://127.0.0.1:8000/v1/models

# DS4のLaunchAgent状態確認
launchctl print gui/$(id -u)/com.kamo.ds4 | head -80

# DS4プロセス確認
ps aux | grep '[d]s4-server'

# DS4再起動
launchctl kickstart -k gui/$(id -u)/com.kamo.ds4

# DS4停止
launchctl bootout gui/$(id -u) $HOME/Library/LaunchAgents/com.kamo.ds4.plist

# 標準ログ確認
tail -n 100 $HOME/Library/Logs/ds4-server.out.log

# エラーログ確認
tail -n 100 $HOME/Library/Logs/ds4-server.err.log

# Hermes設定確認
hermes config show

# Hermes設定チェック
hermes config check

# Hermes起動
hermes

24. まとめ

DS4 / DwarfStar 4 を使うことで、DeepSeek V4 Flash をローカルMac上でAIエージェントのバックエンドとして利用できます。

通常フローは次です。

1. $HOME/llm に ds4 を git clone
2. make でビルド
3. ./download_model.sh q2-imatrix でモデルをダウンロード
4. ./ds4 で単体確認
5. ./ds4-server で手動サーバー確認
6. Hermesの model / providers セクションを ds4-launch / deepseek-v4-flash に変更
7. LaunchAgentで常駐化

特に重要なのは、通常は ./download_model.sh q2-imatrix を使えば ds4flash.gguf が用意されるため、手動でシンボリックリンクを貼る必要はないという点です。

シンボリックリンクの張り替えは、DS4ディレクトリを途中で移動した場合などの特殊ケースとして扱います。

今回のおすすめ運用は次です。

DS4: LaunchAgent常駐
Context length: 300000
KV Disk Cache: 128GB
Hermes backend: ds4-launch (registered provider)
Model: deepseek-v4-flash
Endpoint: http://127.0.0.1:8000/v1

まずは300k contextで安定運用し、必要に応じて500kや1Mへ広げるのが現実的です。


参考リンク

GitHubで編集を提案

Discussion