HelloSun commited on
Commit
d2cda59
·
verified ·
1 Parent(s): b81f07b

build.sh: serve Q4_1 on port 20000 and configure pi coding agent

Browse files
Files changed (1) hide show
  1. build.sh +184 -8
build.sh CHANGED
@@ -1,9 +1,185 @@
1
  #!/bin/bash
2
- # Build llama.cpp at patches/BASE_COMMIT with the flint CPU patch (Xeon with AVX512-VNNI + AMX).
3
- set -e
4
- git clone https://github.com/ggml-org/llama.cpp && cd llama.cpp
5
- git fetch --depth 1 origin $(cat ../patches/BASE_COMMIT) && git checkout $(cat ../patches/BASE_COMMIT)
6
- git apply ../patches/flint-cpu-opt.patch
7
- cmake -B build -DCMAKE_BUILD_TYPE=Release -DGGML_NATIVE=ON -DGGML_CUDA=OFF -DLLAMA_CURL=OFF
8
- cmake --build build -j$(nproc) --target llama-cli llama-server llama-bench llama-perplexity
9
- # run: taskset -c 0-15 build/bin/llama-cli -m flint-UD-Q4_K_XL.gguf -t 16 -fa on -lm mlock
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  #!/bin/bash
2
+ # Build llama.cpp at patches/BASE_COMMIT with the flint CPU patch (Xeon with AVX512-VNNI + AMX),
3
+ # then serve the Q4_1 model on http://127.0.0.1:20000 and point the pi coding agent at it.
4
+ #
5
+ # Overridable environment variables:
6
+ # MODEL_FILE (default flint-int4-q4_1.gguf)
7
+ # LLAMA_PORT (default 20000)
8
+ # MODEL_ALIAS (default flint-q4_1)
9
+ # CONTEXT_SIZE (default 32768)
10
+ # LLAMA_THREADS (default nproc)
11
+ # LLAMA_HOST (default 127.0.0.1)
12
+ set -euo pipefail
13
+
14
+ ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
15
+ cd "$ROOT"
16
+
17
+ MODEL_FILE="${MODEL_FILE:-flint-int4-q4_1.gguf}"
18
+ MODEL_REPO="${MODEL_REPO:-HelloSun/flint_cpu_opt}"
19
+ LLAMA_PORT="${LLAMA_PORT:-20000}"
20
+ MODEL_ALIAS="${MODEL_ALIAS:-flint-q4_1}"
21
+ CONTEXT_SIZE="${CONTEXT_SIZE:-32768}"
22
+ LLAMA_THREADS="${LLAMA_THREADS:-$(nproc 2>/dev/null || echo 4)}"
23
+ LLAMA_HOST="${LLAMA_HOST:-127.0.0.1}"
24
+ MODEL_PATH="$ROOT/$MODEL_FILE"
25
+ SERVER_BIN="$ROOT/llama.cpp/build/bin/llama-server"
26
+ PIDFILE="$HOME/llama-server.pid"
27
+ LOGFILE="$HOME/llama-server.log"
28
+ PI_MODELS_JSON="$HOME/.pi/agent/models.json"
29
+ PI_PROVIDER_ID="llama-cpp-local"
30
+ PI_MODEL_ID="$MODEL_ALIAS"
31
+
32
+ info() { echo -e "\033[36m[build.sh]\033[0m $*"; }
33
+ ok() { echo -e "\033[32m[build.sh]\033[0m $*"; }
34
+ warn() { echo -e "\033[33m[build.sh]\033[0m $*" >&2; }
35
+
36
+ mkdir -p "$HOME/.local/bin" "$(dirname "$PI_MODELS_JSON")"
37
+
38
+ # ── 1. Build llama.cpp (skip when the binary is already there) ────────────────
39
+ if [[ ! -x "$SERVER_BIN" ]]; then
40
+ if [[ ! -f "$ROOT/patches/BASE_COMMIT" || ! -f "$ROOT/patches/flint-cpu-opt.patch" ]]; then
41
+ warn "缺少 patches/BASE_COMMIT 或 patches/flint-cpu-opt.patch,無法套用 flint patch"
42
+ exit 1
43
+ fi
44
+ if [[ ! -d "$ROOT/llama.cpp/.git" ]]; then
45
+ info "clone llama.cpp"
46
+ git clone https://github.com/ggml-org/llama.cpp "$ROOT/llama.cpp"
47
+ fi
48
+ cd "$ROOT/llama.cpp"
49
+ BASE_COMMIT="$(cat "$ROOT/patches/BASE_COMMIT")"
50
+ info "checkout llama.cpp base commit $BASE_COMMIT"
51
+ git fetch --depth 1 origin "$BASE_COMMIT" || true
52
+ git checkout "$BASE_COMMIT"
53
+ if ! git apply --reverse --check "$ROOT/patches/flint-cpu-opt.patch" 2>/dev/null; then
54
+ git apply "$ROOT/patches/flint-cpu-opt.patch"
55
+ fi
56
+ info "cmake configure (GGML_NATIVE=ON, CUDA off)"
57
+ cmake -B build -DCMAKE_BUILD_TYPE=Release -DGGML_NATIVE=ON -DGGML_CUDA=OFF -DLLAMA_CURL=OFF
58
+ info "cmake build (llama-server, -j$LLAMA_THREADS)"
59
+ cmake --build build -j"$LLAMA_THREADS" --target llama-server
60
+ cd "$ROOT"
61
+ else
62
+ ok "llama-server 已存在,跳過編譯:$SERVER_BIN"
63
+ fi
64
+
65
+ # ── 2. Make sure the Q4_1 model is present ───────────────────────────────────
66
+ if [[ ! -s "$MODEL_PATH" ]]; then
67
+ info "下載模型 $MODEL_REPO/$MODEL_FILE(約 24 GiB,支援續傳)"
68
+ URL="https://huggingface.co/$MODEL_REPO/resolve/main/$MODEL_FILE?download=true"
69
+ if command -v hf >/dev/null 2>&1; then
70
+ hf download "$MODEL_REPO" "$MODEL_FILE" --local-dir "$ROOT" || \
71
+ curl -L -C - --retry 3 --retry-delay 5 "$URL" -o "$MODEL_PATH"
72
+ else
73
+ curl -L -C - --retry 3 --retry-delay 5 "$URL" -o "$MODEL_PATH"
74
+ fi
75
+ fi
76
+ if [[ ! -s "$MODEL_PATH" ]]; then
77
+ warn "模型不存在或下載失敗:$MODEL_PATH"
78
+ exit 1
79
+ fi
80
+ ok "模型:$MODEL_PATH"
81
+
82
+ # ── 3. Install pi if needed, and configure it to use this llama-server ───────
83
+ export PATH="$HOME/.local/bin:$HOME/.pi/bin:${XDG_DATA_HOME:-$HOME/.local/share}/pi-node/current/bin:$PATH"
84
+ if ! command -v pi >/dev/null 2>&1; then
85
+ if command -v npm >/dev/null 2>&1; then
86
+ info "安裝 pi coding agent 到 $HOME/.local"
87
+ npm install -g --ignore-scripts --no-fund --no-audit --progress=false \
88
+ --prefix "$HOME/.local" @earendil-works/pi-coding-agent || warn "pi 安裝失敗"
89
+ else
90
+ warn "找不到 npm,略過 pi 安裝(僅寫入設定)"
91
+ fi
92
+ fi
93
+
94
+ info "設定 pi 使用本地 llama-server:http://127.0.0.1:$LLAMA_PORT/v1"
95
+ python3 - "$PI_MODELS_JSON" "$LLAMA_PORT" "$PI_MODEL_ID" "$PI_PROVIDER_ID" "$CONTEXT_SIZE" "$MODEL_ALIAS" <<'PY'
96
+ import json, os, sys
97
+ path, port, model_id, provider, ctx_size, alias = sys.argv[1:7]
98
+ ctx_size = int(ctx_size)
99
+ os.makedirs(os.path.dirname(path), exist_ok=True)
100
+ cfg = {"providers": {}}
101
+ if os.path.exists(path):
102
+ try:
103
+ with open(path) as f:
104
+ loaded = json.load(f)
105
+ if isinstance(loaded, dict):
106
+ cfg = loaded
107
+ cfg.setdefault("providers", {})
108
+ except Exception as exc:
109
+ print(f"[WARN] 無法解析舊 models.json,將覆蓋:{exc}")
110
+ cfg["providers"][provider] = {
111
+ "baseUrl": f"http://127.0.0.1:{port}/v1",
112
+ "api": "openai-completions",
113
+ "apiKey": "not-needed",
114
+ "compat": {"supportsDeveloperRole": True, "supportsReasoningEffort": False},
115
+ "models": [{
116
+ "id": model_id,
117
+ "name": f"Flint Q4_1 (Local {alias})",
118
+ "reasoning": True,
119
+ "input": ["text"],
120
+ "contextWindow": ctx_size,
121
+ "maxTokens": ctx_size,
122
+ "cost": {"input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0},
123
+ }],
124
+ }
125
+ with open(path, "w") as f:
126
+ json.dump(cfg, f, indent=2)
127
+ print(f"[build.sh] 已寫入 {path}")
128
+ PY
129
+
130
+ WRAPPER="$HOME/.local/bin/pi-local"
131
+ cat > "$WRAPPER" <<EOS
132
+ #!/usr/bin/env bash
133
+ exec pi --provider $PI_PROVIDER_ID --model $PI_MODEL_ID "\$@"
134
+ EOS
135
+ chmod +x "$WRAPPER"
136
+ ok "pi-local wrapper:$WRAPPER"
137
+
138
+ # ── 4. Start llama-server on port 20000 ──────────────────────────────────────
139
+ if curl -sf "http://127.0.0.1:$LLAMA_PORT/health" >/dev/null 2>&1; then
140
+ ok "llama-server 已在 127.0.0.1:$LLAMA_PORT 執行,沿用"
141
+ else
142
+ if [[ -f "$PIDFILE" ]]; then
143
+ OLD_PID="$(cat "$PIDFILE" 2>/dev/null || true)"
144
+ if [[ -n "$OLD_PID" ]] && kill -0 "$OLD_PID" 2>/dev/null; then
145
+ info "停止舊 llama-server (PID $OLD_PID)"
146
+ kill "$OLD_PID" 2>/dev/null || true
147
+ sleep 2
148
+ kill -9 "$OLD_PID" 2>/dev/null || true
149
+ fi
150
+ fi
151
+ info "啟動 llama-server:127.0.0.1:$LLAMA_PORT(model=$MODEL_FILE, alias=$MODEL_ALIAS, ctx=$CONTEXT_SIZE, threads=$LLAMA_THREADS)"
152
+ nohup "$SERVER_BIN" \
153
+ -m "$MODEL_PATH" \
154
+ --alias "$MODEL_ALIAS" \
155
+ -t "$LLAMA_THREADS" \
156
+ -fa on \
157
+ --jinja \
158
+ -c "$CONTEXT_SIZE" \
159
+ --host "$LLAMA_HOST" \
160
+ --port "$LLAMA_PORT" \
161
+ >"$LOGFILE" 2>&1 &
162
+ echo $! > "$PIDFILE"
163
+ info "llama-server PID: $(cat "$PIDFILE"),log: $LOGFILE"
164
+
165
+ READY=0
166
+ for _ in $(seq 1 120); do
167
+ if curl -sf "http://127.0.0.1:$LLAMA_PORT/health" >/dev/null 2>&1; then
168
+ READY=1
169
+ break
170
+ fi
171
+ if ! kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then
172
+ warn "llama-server 程序已結束,最後 40 行 log:"
173
+ tail -n 40 "$LOGFILE" >&2 || true
174
+ break
175
+ fi
176
+ sleep 5
177
+ done
178
+ if [[ "$READY" -ne 1 ]]; then
179
+ warn "llama-server 未就緒(見 $LOGFILE)"
180
+ exit 1
181
+ fi
182
+ fi
183
+
184
+ ok "完成:llama-server http://127.0.0.1:$LLAMA_PORT/v1(model=$PI_MODEL_ID, provider=$PI_PROVIDER_ID)"
185
+ ok "pi 用法:pi --provider $PI_PROVIDER_ID --model $PI_MODEL_ID 或 pi-local"