@@ -1,46 +1,29 @@ |
| 1 | 1 | #!/usr/bin/env bash |
| 2 | | -# Bump the vendored llama.cpp submodule to a new tag and re-extract the |
| 3 | | -# pre-tokenizer hash table. |
| 4 | | -# |
| 5 | | -# This script is a skeleton — Sprint 11 adds the actual submodule at |
| 6 | | -# `vendor/llama.cpp`. Sprint 06 ships the script + the shape of |
| 7 | | -# `vendor/llama_cpp_pretokenizer_hashes.json` so the compatibility |
| 8 | | -# probes (base_models/probes.py) have somewhere to read from. |
| 2 | +# Bump the vendored llama.cpp submodule, build its tools, and refresh |
| 3 | +# the pre-tokenizer hash table. |
| 9 | 4 | # |
| 10 | 5 | # Usage: |
| 11 | | -# scripts/bump-llama-cpp.sh <tag> |
| 12 | | -# Fast-forward submodule to `<tag>`, re-extract hashes, stage. |
| 6 | +# scripts/bump-llama-cpp.sh bump <tag> |
| 7 | +# Fast-forward submodule to <tag>, re-extract hashes, write VERSION, |
| 8 | +# stage changes. |
| 9 | +# scripts/bump-llama-cpp.sh build |
| 10 | +# Build `llama-quantize` (+ siblings) via cmake. Idempotent. |
| 11 | +# scripts/bump-llama-cpp.sh refresh-labels |
| 12 | +# Regenerate vendor/llama_cpp_pretokenizer_hashes.json from the |
| 13 | +# current submodule contents. Does not touch the submodule itself. |
| 13 | 14 | |
| 14 | 15 | set -euo pipefail |
| 15 | 16 | |
| 16 | | -TAG="${1:-}" |
| 17 | | -if [ -z "$TAG" ]; then |
| 18 | | - echo "usage: scripts/bump-llama-cpp.sh <tag>" >&2 |
| 19 | | - exit 2 |
| 20 | | -fi |
| 21 | | - |
| 22 | | -if [ -n "$(git status --porcelain)" ]; then |
| 23 | | - echo "error: working tree must be clean before a submodule bump" >&2 |
| 24 | | - exit 1 |
| 25 | | -fi |
| 26 | | - |
| 27 | 17 | REPO_ROOT="$(git rev-parse --show-toplevel)" |
| 28 | 18 | VENDOR_DIR="$REPO_ROOT/vendor/llama.cpp" |
| 29 | 19 | HASHES_PATH="$REPO_ROOT/vendor/llama_cpp_pretokenizer_hashes.json" |
| 20 | +VERSION_PATH="$VENDOR_DIR/VERSION" |
| 30 | 21 | |
| 31 | | -if [ ! -d "$VENDOR_DIR" ]; then |
| 32 | | - echo "error: $VENDOR_DIR missing — Sprint 11 vendors llama.cpp as a submodule" >&2 |
| 33 | | - exit 1 |
| 34 | | -fi |
| 35 | | - |
| 36 | | -echo "--> fetching tags in $VENDOR_DIR" |
| 37 | | -git -C "$VENDOR_DIR" fetch --tags origin |
| 22 | +cmd="${1:-}" |
| 38 | 23 | |
| 39 | | -echo "--> checking out $TAG" |
| 40 | | -git -C "$VENDOR_DIR" checkout "tags/$TAG" |
| 41 | | - |
| 42 | | -echo "--> re-extracting pre-tokenizer hash labels to $HASHES_PATH" |
| 43 | | -uv run python - <<'PY' |
| 24 | +refresh_labels() { |
| 25 | + echo "--> re-extracting pre-tokenizer hash labels to $HASHES_PATH" |
| 26 | + uv run python - <<'PY' |
| 44 | 27 | import json |
| 45 | 28 | import re |
| 46 | 29 | import sys |
@@ -50,9 +33,11 @@ repo_root = Path.cwd() |
| 50 | 33 | converter = repo_root / "vendor" / "llama.cpp" / "convert_hf_to_gguf.py" |
| 51 | 34 | hashes_path = repo_root / "vendor" / "llama_cpp_pretokenizer_hashes.json" |
| 52 | 35 | |
| 36 | +if not converter.is_file(): |
| 37 | + print(f"ERROR: {converter} not found", file=sys.stderr) |
| 38 | + sys.exit(1) |
| 39 | + |
| 53 | 40 | source = converter.read_text(encoding="utf-8", errors="replace") |
| 54 | | -# llama.cpp declares pre-tokenizer labels inside `get_vocab_base_pre` |
| 55 | | -# via `res = "<label>"` assignments. |
| 56 | 41 | pattern = re.compile(r"""\bres\s*=\s*["']([^"']+)["']""") |
| 57 | 42 | labels = sorted(set(pattern.findall(source))) |
| 58 | 43 | if not labels: |
@@ -63,14 +48,83 @@ if not labels: |
| 63 | 48 | hashes_path.write_text(json.dumps(labels, indent=2) + "\n", encoding="utf-8") |
| 64 | 49 | print(f"wrote {len(labels)} labels to {hashes_path}") |
| 65 | 50 | PY |
| 51 | +} |
| 66 | 52 | |
| 67 | | -echo "--> staging changes" |
| 68 | | -git -C "$REPO_ROOT" add vendor/llama.cpp vendor/llama_cpp_pretokenizer_hashes.json |
| 53 | +do_bump() { |
| 54 | + local tag="${1:-}" |
| 55 | + if [ -z "$tag" ]; then |
| 56 | + echo "usage: scripts/bump-llama-cpp.sh bump <tag>" >&2 |
| 57 | + exit 2 |
| 58 | + fi |
| 59 | + if [ -n "$(git status --porcelain)" ]; then |
| 60 | + echo "error: working tree must be clean before a submodule bump" >&2 |
| 61 | + exit 1 |
| 62 | + fi |
| 63 | + if [ ! -d "$VENDOR_DIR" ]; then |
| 64 | + echo "error: $VENDOR_DIR missing — initialize the submodule first:" >&2 |
| 65 | + echo " git submodule add https://github.com/ggerganov/llama.cpp vendor/llama.cpp" >&2 |
| 66 | + exit 1 |
| 67 | + fi |
| 69 | 68 | |
| 70 | | -cat <<EOF |
| 69 | + echo "--> fetching tags in $VENDOR_DIR" |
| 70 | + git -C "$VENDOR_DIR" fetch --tags origin |
| 71 | + echo "--> checking out $tag" |
| 72 | + git -C "$VENDOR_DIR" checkout "tags/$tag" |
| 73 | + |
| 74 | + echo "--> writing $VERSION_PATH" |
| 75 | + echo "$tag" > "$VERSION_PATH" |
| 76 | + |
| 77 | + refresh_labels |
| 78 | + |
| 79 | + echo "--> staging changes" |
| 80 | + git -C "$REPO_ROOT" add vendor/llama.cpp vendor/llama_cpp_pretokenizer_hashes.json |
| 81 | + |
| 82 | + cat <<EOF |
| 71 | 83 | Done. Review the staged diff and commit with: |
| 72 | | - git commit -m "chore: bump llama.cpp to $TAG + refresh pre-tokenizer hashes" |
| 84 | + git commit -m "chore: bump llama.cpp to $tag + refresh pre-tokenizer hashes" |
| 73 | 85 | |
| 74 | | -Then re-run the registry probe suite: |
| 86 | +Then build the binaries: |
| 87 | + scripts/bump-llama-cpp.sh build |
| 88 | + |
| 89 | +And re-run the registry probe suite: |
| 75 | 90 | uv run python scripts/refresh-registry.py |
| 76 | 91 | EOF |
| 92 | +} |
| 93 | + |
| 94 | +do_build() { |
| 95 | + if [ ! -d "$VENDOR_DIR" ]; then |
| 96 | + echo "error: $VENDOR_DIR missing — run 'bump <tag>' first" >&2 |
| 97 | + exit 1 |
| 98 | + fi |
| 99 | + echo "--> configuring llama.cpp via cmake" |
| 100 | + cmake -S "$VENDOR_DIR" -B "$VENDOR_DIR/build" -DCMAKE_BUILD_TYPE=Release |
| 101 | + echo "--> building llama-quantize + siblings" |
| 102 | + cmake --build "$VENDOR_DIR/build" --target llama-quantize --config Release |
| 103 | + if [ -f "$VENDOR_DIR/build/bin/llama-quantize" ]; then |
| 104 | + echo "OK: $VENDOR_DIR/build/bin/llama-quantize" |
| 105 | + else |
| 106 | + echo "error: build finished but llama-quantize not found under build/bin" >&2 |
| 107 | + exit 1 |
| 108 | + fi |
| 109 | +} |
| 110 | + |
| 111 | +case "$cmd" in |
| 112 | + bump) |
| 113 | + do_bump "${2:-}" |
| 114 | + ;; |
| 115 | + build) |
| 116 | + do_build |
| 117 | + ;; |
| 118 | + refresh-labels) |
| 119 | + refresh_labels |
| 120 | + ;; |
| 121 | + "") |
| 122 | + echo "usage: scripts/bump-llama-cpp.sh <bump|build|refresh-labels> [args]" >&2 |
| 123 | + exit 2 |
| 124 | + ;; |
| 125 | + *) |
| 126 | + echo "unknown command: $cmd" >&2 |
| 127 | + echo "usage: scripts/bump-llama-cpp.sh <bump|build|refresh-labels> [args]" >&2 |
| 128 | + exit 2 |
| 129 | + ;; |
| 130 | +esac |