reorganize: add Justfile, move latency benchmarking to subdir, remove notes.md
- Justfile: build, download-model, worker, serve, local, stop, test, diff
- latency-benchmarking/: demo.sh, bench.sh, bench-b2b.sh, latency-proxy.py, measure.py
- notes.md -> latency-benchmarking/README.md (reference for that tooling)
- Scripts updated to resolve llama.cpp from parent dir
2026-02-12 20:16:10 +11:00
# Distributed LLM Inference — build & run tasks
2026-04-25 18:57:47 +10:00
llama_dir := env( "MESH_LLM_LLAMA_DIR" , ".deps/llama.cpp" )
2026-05-05 11:48:40 +10:00
llama_build_root := env( "MESH_LLM_LLAMA_BUILD_ROOT" , ".deps/llama-build" )
2026-05-08 12:11:14 +10:00
mesh_dir := "crates/mesh-llm"
ui_dir := "crates/mesh-llm-ui"
2026-06-10 05:18:25 -04:00
website_dir := "website"
2026-03-29 11:45:16 +11:00
home_dir := if os_family( ) = = "windows" { env( "USERPROFILE" ) } else { env( "HOME" ) }
2026-04-04 19:25:09 +11:00
xdg_cache_dir := env( "XDG_CACHE_HOME" , home_dir / ".cache" )
hf_home := env( "HF_HOME" , xdg_cache_dir / "huggingface" )
models_dir := env( "HF_HUB_CACHE" , hf_home / "hub" )
reorganize: add Justfile, move latency benchmarking to subdir, remove notes.md
- Justfile: build, download-model, worker, serve, local, stop, test, diff
- latency-benchmarking/: demo.sh, bench.sh, bench-b2b.sh, latency-proxy.py, measure.py
- notes.md -> latency-benchmarking/README.md (reference for that tooling)
- Scripts updated to resolve llama.cpp from parent dir
2026-02-12 20:16:10 +11:00
model := models_dir / "GLM-4.7-Flash-Q4_K_M.gguf"
2026-05-10 08:14:22 +10:00
# Build for the current platform.
default : build
[ p r i v a t e ]
[ u n i x ]
2026-05-18 22:58:00 -04:00
with-lld *COMMAND :
2026-05-10 08:14:22 +10:00
#!/usr/bin/env bash
set -euo pipefail
2026-05-18 22:58:00 -04:00
lld = ""
2026-05-10 08:14:22 +10:00
case " $( uname -s) " in
Linux)
if ! command -v ld.lld >/dev/null 2>& 1; then
cat >& 2 <<'EOF'
Error: LLVM ld.lld was not found.
lld is required for faster Rust builds ( measured up to 26% faster locally) .
Install lld, then rerun the just command. Common Linux packages:
Ubuntu/Debian: sudo apt-get update && sudo apt-get install -y lld
Fedora: sudo dnf install lld
Arch Linux: sudo pacman -S lld
openSUSE: sudo zypper install lld
The build requires ld.lld to be available on PATH.
EOF
exit 1
fi
2026-05-18 22:58:00 -04:00
lld = "lld"
2026-05-10 08:14:22 +10:00
; ;
Darwin)
if command -v ld64.lld >/dev/null 2>& 1; then
lld = " $( command -v ld64.lld) "
elif command -v brew >/dev/null 2>& 1; then
lld_prefix = " $( brew --prefix lld 2>/dev/null || true ) "
if [ [ -n " $lld_prefix " && -x " $lld_prefix /bin/ld64.lld " ] ] ; then
lld = " $lld_prefix /bin/ld64.lld "
fi
fi
if [ [ -z " $lld " ] ] ; then
for candidate in /opt/homebrew/opt/lld/bin/ld64.lld /usr/local/opt/lld/bin/ld64.lld; do
if [ [ -x " $candidate " ] ] ; then
lld = " $candidate "
break
fi
done
fi
if [ [ -z " $lld " ] ] ; then
cat >& 2 <<'EOF'
Error: LLVM ld64.lld was not found.
lld is required for faster Rust builds ( measured up to 26% faster locally) .
Install lld, then rerun the just command:
brew install lld
If Homebrew installed lld but it is not on PATH, Mesh-LLM also checks:
$( brew --prefix lld) /bin/ld64.lld
/opt/homebrew/opt/lld/bin/ld64.lld
/usr/local/opt/lld/bin/ld64.lld
EOF
exit 1
fi
; ;
*)
2026-05-18 22:58:00 -04:00
echo " Unsupported OS for lld linker setup: $( uname -s) " >& 2
2026-05-10 08:14:22 +10:00
exit 1
; ;
esac
2026-05-18 22:58:00 -04:00
export RUSTFLAGS = " ${ RUSTFLAGS : + $RUSTFLAGS } -C link-arg=-fuse-ld= $lld "
exec { { COMMAND } }
2026-05-10 08:14:22 +10:00
[ p r i v a t e ]
[ w i n d o w s ]
2026-05-18 22:58:00 -04:00
with-lld *COMMAND :
@powershell -NoProfile -ExecutionPolicy Bypass -Command " $$ ErrorActionPreference = 'Stop'; $$ linker = $$ null; try { $$ sysroot = (& rustc --print sysroot).Trim(); foreach ( $$ target in @('x86_64-pc-windows-msvc', 'aarch64-pc-windows-msvc')) { $$ candidate = Join-Path $$ sysroot \"lib\rustlib\$ $target \bin\rust-lld.exe\"; if (Test-Path $$ candidate) { $$ linker = $$ candidate; break } } } catch {}; if (-not $$ linker) { foreach ( $$ name in @('rust-lld.exe', 'lld-link.exe')) { $$ command = Get-Command $$ name -ErrorAction SilentlyContinue; if ( $$ command) { $$ linker = $$ command.Source; break } } }; if (-not $$ linker) { Write-Error \"LLVM lld was not found for the Windows MSVC target.`n`nlld is required for faster Rust builds (measured up to 26% faster locally).`n`nInstall one of these, then rerun the just command:`n rustup component add llvm-tools-preview`n`nOr install LLVM lld-link:`n winget install LLVM.LLVM`n choco install llvm`n`nThe build requires lld. It looks for rust-lld.exe in the active Rust sysroot first, then falls back to rust-lld.exe or lld-link.exe on PATH.\"; exit 1 }; $$ env:CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_LINKER = $$ linker; $$ env:CARGO_TARGET_AARCH64_PC_WINDOWS_MSVC_LINKER = $$ linker; Invoke-Expression '{{ COMMAND }}' "
2026-05-10 08:14:22 +10:00
2026-07-29 10:16:23 -04:00
# Build a local product for the current platform. This is always a
# backend-neutral dynamic host plus an adjacent packaged runtime.
2026-03-25 21:44:12 -04:00
[ m a c o s ]
2026-07-29 10:16:23 -04:00
build backend="" cuda_arch="" rocm_arch="" :
@scripts/build-development-product.sh --backend "{{ backend }}" --cuda-arch "{{ cuda_arch }}" --rocm-arch "{{ rocm_arch }}"
2026-03-25 21:44:12 -04:00
2026-07-29 10:16:23 -04:00
# Fast local iteration build: dynamic host + adjacent native runtime + UI.
2026-05-09 18:49:59 +10:00
[ m a c o s ]
build-dev :
2026-07-29 10:16:23 -04:00
@MESH_LLM_BUILD_PROFILE= dev scripts/build-development-product.sh --profile dev
2026-05-09 18:49:59 +10:00
2026-03-27 21:36:19 +11:00
# Linux overrides:
2026-03-28 17:14:05 +11:00
# just build backend=cpu
2026-03-27 21:36:19 +11:00
# just build backend=cuda cuda_arch='120;86'
# just build backend=rocm rocm_arch='gfx942;gfx90a'
2026-07-29 10:16:23 -04:00
# just build backend=vulkan
2026-03-25 21:44:12 -04:00
[ l i n u x ]
2026-03-27 21:36:19 +11:00
build backend="" cuda_arch="" rocm_arch="" :
2026-07-29 10:16:23 -04:00
@scripts/build-development-product.sh --backend "{{ backend }}" --cuda-arch "{{ cuda_arch }}" --rocm-arch "{{ rocm_arch }}"
2026-03-25 21:44:12 -04:00
2026-07-29 10:16:23 -04:00
# Fast local iteration build: dynamic host + adjacent native runtime + UI.
2026-05-09 18:49:59 +10:00
[ l i n u x ]
build-dev backend="" cuda_arch="" rocm_arch="" :
2026-07-29 10:16:23 -04:00
@MESH_LLM_BUILD_PROFILE= dev scripts/build-development-product.sh --profile dev --backend "{{ backend }}" --cuda-arch "{{ cuda_arch }}" --rocm-arch "{{ rocm_arch }}"
2026-05-09 18:49:59 +10:00
2026-03-29 08:35:43 +11:00
# Windows overrides:
# just build backend=cpu
# just build backend=cuda cuda_arch='120;86'
# just build backend=rocm rocm_arch='gfx942;gfx90a'
2026-07-29 10:16:23 -04:00
# just build backend=vulkan
2026-03-29 08:35:43 +11:00
[ w i n d o w s ]
build backend="" cuda_arch="" rocm_arch="" :
2026-07-29 10:16:23 -04:00
@powershell -NoProfile -ExecutionPolicy Bypass -File scripts/build-windows.ps1 -Backend "{{ backend }}" -CudaArch "{{ cuda_arch }}" -RocmArch "{{ rocm_arch }}" -DynamicHost
2026-03-25 21:44:12 -04:00
2026-07-29 10:16:23 -04:00
# Fast local iteration build: dynamic host + adjacent native runtime + UI.
2026-05-09 18:49:59 +10:00
[ w i n d o w s ]
build-dev backend="" cuda_arch="" rocm_arch="" :
2026-07-29 10:16:23 -04:00
@powershell -NoProfile -ExecutionPolicy Bypass -Command " $env :MESH_LLM_BUILD_PROFILE='dev'; & './scripts/build-windows.ps1' -Backend '{{ backend }}' -CudaArch '{{ cuda_arch }}' -RocmArch '{{ rocm_arch }}' -DynamicHost "
2026-05-09 18:49:59 +10:00
2026-07-29 10:16:23 -04:00
# Low-level static ABI primitive. This builds only the native runtime; it never
# builds a MeshLLM host. Use `just build` for normal development.
2026-03-25 21:44:12 -04:00
build-mac :
2026-07-29 10:16:23 -04:00
@scripts/package-native-runtime.sh --build --backend metal
reorganize: add Justfile, move latency benchmarking to subdir, remove notes.md
- Justfile: build, download-model, worker, serve, local, stop, test, diff
- latency-benchmarking/: demo.sh, bench.sh, bench-b2b.sh, latency-proxy.py, measure.py
- notes.md -> latency-benchmarking/README.md (reference for that tooling)
- Scripts updated to resolve llama.cpp from parent dir
2026-02-12 20:16:10 +11:00
2026-07-29 10:16:23 -04:00
# Low-level static ABI primitive. This builds only the native runtime; it never
# builds a MeshLLM host. Use `just build` for normal development.
2026-03-27 21:36:19 +11:00
build-linux backend="" cuda_arch="" rocm_arch="" :
2026-07-29 10:16:23 -04:00
#!/usr/bin/env bash
set -euo pipefail
backend = "{{ backend }}"
[ [ -n " $backend " ] ] || backend = cpu
LLAMA_STAGE_CUDA_ARCHITECTURES = "{{ cuda_arch }}" LLAMA_STAGE_AMDGPU_TARGETS = "{{ rocm_arch }}" scripts/package-native-runtime.sh --build --backend " $backend "
2026-03-27 18:30:22 +11:00
2026-07-29 10:16:23 -04:00
# Backward-compatible spelling for the explicit native-runtime primitive.
2026-05-05 11:48:40 +10:00
[ l i n u x ]
build-runtime backend="" cuda_arch="" rocm_arch="" :
2026-07-29 10:16:23 -04:00
@backend= "{{ backend }}" ; \
[ [ -n " $$ backend " ] ] || backend = cpu; \
LLAMA_STAGE_CUDA_ARCHITECTURES = "{{ cuda_arch }}" LLAMA_STAGE_AMDGPU_TARGETS = "{{ rocm_arch }}" scripts/package-native-runtime.sh --build --backend " $$ backend "
2026-05-05 11:48:40 +10:00
2026-03-27 18:30:22 +11:00
# Build release artifacts for the current platform.
2026-06-30 22:42:09 -04:00
# Prepare, publish, and watch a GitHub release from main.
release version *ARGS :
@scripts/release.sh "{{ version }}" { { ARGS } }
2026-07-29 10:16:23 -04:00
# Build the backend-neutral release host once for the current platform.
release-host-build :
2026-03-27 18:30:22 +11:00
@scripts/build-release.sh
2026-03-25 21:44:12 -04:00
2026-07-29 10:16:23 -04:00
# Build one packageable native runtime for the current platform.
release-runtime-build backend="" target="" :
#!/usr/bin/env bash
set -euo pipefail
selected_backend = "{{ backend }}"
if [ [ -z " $selected_backend " ] ] ; then
if [ [ " $( uname -s) " = = Darwin ] ] ; then selected_backend = metal; else selected_backend = cpu; fi
fi
if [ [ -n "{{ target }}" ] ] ; then
scripts/package-native-runtime.sh --build --backend " $selected_backend " --target "{{ target }}"
else
scripts/package-native-runtime.sh --build --backend " $selected_backend "
fi
# Build the backend-neutral host and the default runtime for this platform.
release-build : release -host -build release -runtime -build
2026-05-29 17:20:36 -04:00
# Build a Linux aarch64 CPU release artifact on a native aarch64 runner.
2026-07-29 10:16:23 -04:00
release-build-aarch64 : release -host -build
@scripts/package-native-runtime.sh --build --backend cpu --target aarch64-unknown-linux-gnu
2026-04-14 02:57:38 -04:00
2026-05-29 17:20:36 -04:00
# Build a Linux aarch64 CUDA release artifact (Jetson/Orin).
# SM arches selected by MESH_CUDA_VERSION env (set by CI matrix).
2026-07-29 10:16:23 -04:00
release-build-aarch64-cuda : release -host -build
@cuda_version= " ${ MESH_CUDA_VERSION :- 12 } " ; \
MESH_LLM_CUDA_TOOLKIT_MAJOR = " ${ MESH_LLM_CUDA_TOOLKIT_MAJOR :- ${ cuda_version %%.* } } " \
2026-08-09 10:35:02 +10:00
LLAMA_STAGE_CUDA_ARCHITECTURES = " $( if [ [ " $cuda_version " = = 13.* ] ] ; then echo '75;80;86;87;89;90;110' ; else echo '61;75;80;86;87;89;90' ; fi ) " \
2026-07-29 10:16:23 -04:00
scripts/package-native-runtime.sh --build --backend cuda --target aarch64-unknown-linux-gnu
2026-05-29 17:20:36 -04:00
2026-05-05 11:48:40 +10:00
# Prepare the pinned llama.cpp checkout and apply the Mesh-LLM ABI patch queue.
2026-04-26 08:19:49 +10:00
llama-prepare :
@scripts/prepare-llama.sh pinned
2026-05-05 11:48:40 +10:00
# Prepare llama.cpp at upstream master and apply the Mesh-LLM ABI patch queue.
2026-04-26 08:19:49 +10:00
llama-prepare-latest :
@scripts/prepare-llama.sh latest
2026-05-05 11:48:40 +10:00
# Build the patched llama.cpp ABI static libraries.
llama-build : llama -prepare
@scripts/build-llama.sh
2026-03-29 08:57:02 +11:00
release-build-windows :
2026-07-29 10:16:23 -04:00
@powershell -NoProfile -ExecutionPolicy Bypass -File scripts/build-windows.ps1 -Backend cpu -BuildProfile release -DynamicHost
release-host-build-windows :
@powershell -NoProfile -ExecutionPolicy Bypass -File scripts/build-windows.ps1 -BuildProfile release -HostOnly
2026-03-29 08:35:43 +11:00
2026-05-29 17:20:36 -04:00
# Build a Linux CUDA release artifact.
# SM arches selected by MESH_CUDA_VERSION env (set by CI matrix).
2026-07-29 10:16:23 -04:00
release-build-cuda : release -host -build
@cuda_version= " ${ MESH_CUDA_VERSION :- 12 } " ; \
MESH_LLM_CUDA_TOOLKIT_MAJOR = " ${ MESH_LLM_CUDA_TOOLKIT_MAJOR :- ${ cuda_version %%.* } } " \
2026-08-09 10:35:02 +10:00
LLAMA_STAGE_CUDA_ARCHITECTURES = " $( if [ [ " $cuda_version " = = 13.* ] ] ; then echo '75;80;86;87;89;90;100;103;120;121' ; else echo '61;75;80;86;87;89;90' ; fi ) " \
2026-07-29 10:16:23 -04:00
scripts/package-native-runtime.sh --build --backend cuda --target x86_64-unknown-linux-gnu
ci: dual-lane CUDA releases (cuda on 12.6.3, cuda-blackwell on 12.8) (#355)
* ci: dual-lane CUDA releases (cuda on 12.6.3, cuda-blackwell on 12.8)
Published v0.60.3 CUDA bundle crashes at the first matmul on A30/A100
(SM 8.0) with `CUDA error: device kernel image is invalid` when run
against R535-series drivers. Root cause confirmed by A/B build on 29
GPUs (14x A30, 15x A100, driver 535.288.01): nvcc 12.8 emits cubins
whose minor-version metadata the R535 driver (CUDA 12.2 native) rejects
at kernel load, even though sm_80 cubins are physically present. The
same source tree built under CUDA 12.6.3 produces a working bundle on
identical hardware.
A toolkit downgrade alone would drop Blackwell (sm_100/103/120, which
CUDA 12.6 cannot emit). Instead, split the CUDA release into two lanes:
primary -cuda CUDA 12.6.3 sm_75..sm_90 R535+ driver
Blackwell lane -cuda-blackwell CUDA 12.8 adds sm_100/103/120 R550+ driver
Both lanes ship inner binaries named -cuda (the mesh-llm runtime
BinaryFlavor enum has one cuda variant); only the outer archive name
distinguishes them. Users pick the archive matching their driver; both
bundles invoke as `--llama-flavor cuda`.
Changes:
- .github/workflows/release.yml: keep build_linux_cuda on 12.6.3; add a
sibling build_linux_cuda_blackwell job on 12.8, wired into the
publish job's needs list. New Actions variable
vars.CUDA_BLACKWELL_VERSION (fallback 12.8.0) mirrors vars.CUDA_VERSION
(now fallback 12.6.3).
- .github/workflows/ci.yml, .github/workflows/llama-cache-keys.yml: pin
fallback to 12.6.3 for the primary lane; add a second cache key
cuda_blackwell_fat_cache_key so the two lanes do not collide.
- .github/workflows/docker.yml: narrow CUDA_ARCH build-arg to sm_75-90
to match the primary-lane Dockerfile base.
- Justfile: release-build-cuda default arch narrowed to sm_75-90; add
release-build-cuda-blackwell, release-bundle-cuda-blackwell (plus
Windows mirrors); docker-build-cuda gains a cuda_version parameter.
- docker/Dockerfile.cuda: parameterize the three nvidia/cuda FROM lines
via ARG CUDA_VERSION (default 12.6.3) so Blackwell docker builds can
override; ARG CUDA_ARCH default narrowed to sm_75-90. docker image
itself tracks primary lane only for now; Blackwell docker tag is a
planned follow-up.
- scripts/package-release.sh: add cuda-blackwell to linux/x86_64
supported_release_flavors; introduce binary_flavor_for_release_flavor
so cuda-blackwell bundles still name inner binaries llama-server-cuda
etc.
- install.sh: expose cuda-blackwell as an installable flavor and map to
the new archive name.
- mesh-llm/tests/fixtures/release-target-matrix.json: fixture rows for
cuda-blackwell on linux/x86_64 (supported), windows/x86_64 (supported),
linux/aarch64 + macos/aarch64 (unknown) so the xtask release-target
consistency check passes.
- RELEASE.md, README.md, docker/SPEC_COMPLIANCE.md: document both lanes
and the driver-compatibility matrix. Add docs/cuda-release-lanes.md
with the end-to-end rationale.
Verified locally via manual parity tests against install.sh and
scripts/package-release.sh (supported_flavors, asset_name /
versioned_asset_name, release_target_support, bundle_bin_name) for
cpu/cuda/cuda-blackwell on linux/x86_64 and linux/aarch64. A full xtask
repo-consistency run should be re-executed in CI.
Fixes issue #304.
* docker: hoist CUDA_VERSION ARG above first FROM
Without this, the second and third nvidia/cuda FROM lines resolve
${CUDA_VERSION} to empty — Docker drops pre-FROM ARG scope once the
first FROM is parsed (the ui-builder FROM at line 23). BuildKit fails
with:
invalid reference format
nvidia/cuda:-runtime-ubuntu22.04
Caught by a docker build against docker/Dockerfile.cuda on a CUDA 12.6.3
host. Hoisting the ARG above the ui-builder FROM makes it a true global
in scope for every FROM directive. The intermediate re-declarations are
removed — they zero-valued the default and actively broke resolution.
End-to-end verification (ops-grid02, nvidia/cuda:12.6.3-devel):
llama.cpp compile: 435/435 kernels OK
cubin audit:
177 sm_75, 177 sm_80, 177 sm_86, 177 sm_87, 177 sm_89, 177 sm_90
no sm_100/103/120 (primary lane is R535-compatible as designed)
GGML_CUDA_FA_ALL_QUANTS=ON verified in CMakeCache
* ci: drop sm_103 from blackwell arch list — nvcc 12.8.0 does not support it
nvcc 12.8.0 supports sm_100, sm_101, sm_120 but NOT sm_103 — that
compute capability was introduced in a later CUDA release. Caught by a
docker build against docker/Dockerfile.cuda with CUDA_VERSION=12.8.0 on
a CUDA-12.8 host:
nvcc fatal : Unsupported gpu architecture 'compute_103'
Updated Blackwell arch list from 75;80;86;87;89;90;100;103;120 to
75;80;86;87;89;90;100;120. Covers all currently-shipping Blackwell
hardware nvcc 12.8.0 can emit for (B100/B200 via sm_100, RTX 50-series
via sm_120).
Files touched: Justfile, .github/workflows/release.yml,
.github/workflows/llama-cache-keys.yml, docs/cuda-release-lanes.md,
README.md.
* Add BinaryFlavor::CudaBlackwell so release-target tests recognize the new lane
The dual-lane CUDA release introduces a cuda-blackwell tarball, but the
BinaryFlavor enum and supported-combos list did not know about it. With
main's new release_target fixture tests, that surfaced as three panics
for 'unknown fixture flavor: cuda-blackwell'. Teach the enum, the
preferred-devices table, the supported-combos list, the asset suffix,
and the fixture-test flavor parser about the new variant.
* ci: address Copilot review feedback on dual-lane CUDA
Four fixes from Copilot's PR review:
1. release.yml build_linux_cuda_blackwell: add skip_gpu_bundles guard,
needs: prepare_release, and ref: release_sha on checkout so the job
matches the other GPU bundle jobs. Use RELEASE_TAG from
prepare_release.outputs.tag instead of GITHUB_REF_NAME so the
bundle version matches the release commit/tag.
2. scripts/package-release.ps1: separate release flavor (outer archive
name) from binary flavor (inner executable suffix). cuda-blackwell
archives now contain -cuda binaries on Windows, matching the bash
packager so the runtime's BinaryFlavor::Cuda lookup still finds
rpc-server-cuda.exe / llama-server-cuda.exe inside a
mesh-llm-*-cuda-blackwell.zip.
3. docker/SPEC_COMPLIANCE.md Q3: correct the misleading claim that
compute_120 is in release-build-cuda. Describe the lane split so
readers know compute_120 only ships in release-build-cuda-blackwell.
* Address CUDA lane review comments
---------
Co-authored-by: Ventz Petkov <ventz@vpetkov.net>
Co-authored-by: James Dumay <jameswdumay@gmail.com>
2026-05-06 21:34:02 +10:00
2026-08-09 10:35:02 +10:00
release-build-cuda-windows cuda_arch="61;75;80;86;87;89;90" :
2026-07-29 10:16:23 -04:00
@powershell -NoProfile -ExecutionPolicy Bypass -File scripts/build-windows.ps1 -Backend cuda -CudaArch "{{ cuda_arch }}" -BuildProfile release -DynamicHost
ci: dual-lane CUDA releases (cuda on 12.6.3, cuda-blackwell on 12.8) (#355)
* ci: dual-lane CUDA releases (cuda on 12.6.3, cuda-blackwell on 12.8)
Published v0.60.3 CUDA bundle crashes at the first matmul on A30/A100
(SM 8.0) with `CUDA error: device kernel image is invalid` when run
against R535-series drivers. Root cause confirmed by A/B build on 29
GPUs (14x A30, 15x A100, driver 535.288.01): nvcc 12.8 emits cubins
whose minor-version metadata the R535 driver (CUDA 12.2 native) rejects
at kernel load, even though sm_80 cubins are physically present. The
same source tree built under CUDA 12.6.3 produces a working bundle on
identical hardware.
A toolkit downgrade alone would drop Blackwell (sm_100/103/120, which
CUDA 12.6 cannot emit). Instead, split the CUDA release into two lanes:
primary -cuda CUDA 12.6.3 sm_75..sm_90 R535+ driver
Blackwell lane -cuda-blackwell CUDA 12.8 adds sm_100/103/120 R550+ driver
Both lanes ship inner binaries named -cuda (the mesh-llm runtime
BinaryFlavor enum has one cuda variant); only the outer archive name
distinguishes them. Users pick the archive matching their driver; both
bundles invoke as `--llama-flavor cuda`.
Changes:
- .github/workflows/release.yml: keep build_linux_cuda on 12.6.3; add a
sibling build_linux_cuda_blackwell job on 12.8, wired into the
publish job's needs list. New Actions variable
vars.CUDA_BLACKWELL_VERSION (fallback 12.8.0) mirrors vars.CUDA_VERSION
(now fallback 12.6.3).
- .github/workflows/ci.yml, .github/workflows/llama-cache-keys.yml: pin
fallback to 12.6.3 for the primary lane; add a second cache key
cuda_blackwell_fat_cache_key so the two lanes do not collide.
- .github/workflows/docker.yml: narrow CUDA_ARCH build-arg to sm_75-90
to match the primary-lane Dockerfile base.
- Justfile: release-build-cuda default arch narrowed to sm_75-90; add
release-build-cuda-blackwell, release-bundle-cuda-blackwell (plus
Windows mirrors); docker-build-cuda gains a cuda_version parameter.
- docker/Dockerfile.cuda: parameterize the three nvidia/cuda FROM lines
via ARG CUDA_VERSION (default 12.6.3) so Blackwell docker builds can
override; ARG CUDA_ARCH default narrowed to sm_75-90. docker image
itself tracks primary lane only for now; Blackwell docker tag is a
planned follow-up.
- scripts/package-release.sh: add cuda-blackwell to linux/x86_64
supported_release_flavors; introduce binary_flavor_for_release_flavor
so cuda-blackwell bundles still name inner binaries llama-server-cuda
etc.
- install.sh: expose cuda-blackwell as an installable flavor and map to
the new archive name.
- mesh-llm/tests/fixtures/release-target-matrix.json: fixture rows for
cuda-blackwell on linux/x86_64 (supported), windows/x86_64 (supported),
linux/aarch64 + macos/aarch64 (unknown) so the xtask release-target
consistency check passes.
- RELEASE.md, README.md, docker/SPEC_COMPLIANCE.md: document both lanes
and the driver-compatibility matrix. Add docs/cuda-release-lanes.md
with the end-to-end rationale.
Verified locally via manual parity tests against install.sh and
scripts/package-release.sh (supported_flavors, asset_name /
versioned_asset_name, release_target_support, bundle_bin_name) for
cpu/cuda/cuda-blackwell on linux/x86_64 and linux/aarch64. A full xtask
repo-consistency run should be re-executed in CI.
Fixes issue #304.
* docker: hoist CUDA_VERSION ARG above first FROM
Without this, the second and third nvidia/cuda FROM lines resolve
${CUDA_VERSION} to empty — Docker drops pre-FROM ARG scope once the
first FROM is parsed (the ui-builder FROM at line 23). BuildKit fails
with:
invalid reference format
nvidia/cuda:-runtime-ubuntu22.04
Caught by a docker build against docker/Dockerfile.cuda on a CUDA 12.6.3
host. Hoisting the ARG above the ui-builder FROM makes it a true global
in scope for every FROM directive. The intermediate re-declarations are
removed — they zero-valued the default and actively broke resolution.
End-to-end verification (ops-grid02, nvidia/cuda:12.6.3-devel):
llama.cpp compile: 435/435 kernels OK
cubin audit:
177 sm_75, 177 sm_80, 177 sm_86, 177 sm_87, 177 sm_89, 177 sm_90
no sm_100/103/120 (primary lane is R535-compatible as designed)
GGML_CUDA_FA_ALL_QUANTS=ON verified in CMakeCache
* ci: drop sm_103 from blackwell arch list — nvcc 12.8.0 does not support it
nvcc 12.8.0 supports sm_100, sm_101, sm_120 but NOT sm_103 — that
compute capability was introduced in a later CUDA release. Caught by a
docker build against docker/Dockerfile.cuda with CUDA_VERSION=12.8.0 on
a CUDA-12.8 host:
nvcc fatal : Unsupported gpu architecture 'compute_103'
Updated Blackwell arch list from 75;80;86;87;89;90;100;103;120 to
75;80;86;87;89;90;100;120. Covers all currently-shipping Blackwell
hardware nvcc 12.8.0 can emit for (B100/B200 via sm_100, RTX 50-series
via sm_120).
Files touched: Justfile, .github/workflows/release.yml,
.github/workflows/llama-cache-keys.yml, docs/cuda-release-lanes.md,
README.md.
* Add BinaryFlavor::CudaBlackwell so release-target tests recognize the new lane
The dual-lane CUDA release introduces a cuda-blackwell tarball, but the
BinaryFlavor enum and supported-combos list did not know about it. With
main's new release_target fixture tests, that surfaced as three panics
for 'unknown fixture flavor: cuda-blackwell'. Teach the enum, the
preferred-devices table, the supported-combos list, the asset suffix,
and the fixture-test flavor parser about the new variant.
* ci: address Copilot review feedback on dual-lane CUDA
Four fixes from Copilot's PR review:
1. release.yml build_linux_cuda_blackwell: add skip_gpu_bundles guard,
needs: prepare_release, and ref: release_sha on checkout so the job
matches the other GPU bundle jobs. Use RELEASE_TAG from
prepare_release.outputs.tag instead of GITHUB_REF_NAME so the
bundle version matches the release commit/tag.
2. scripts/package-release.ps1: separate release flavor (outer archive
name) from binary flavor (inner executable suffix). cuda-blackwell
archives now contain -cuda binaries on Windows, matching the bash
packager so the runtime's BinaryFlavor::Cuda lookup still finds
rpc-server-cuda.exe / llama-server-cuda.exe inside a
mesh-llm-*-cuda-blackwell.zip.
3. docker/SPEC_COMPLIANCE.md Q3: correct the misleading claim that
compute_120 is in release-build-cuda. Describe the lane split so
readers know compute_120 only ships in release-build-cuda-blackwell.
* Address CUDA lane review comments
---------
Co-authored-by: Ventz Petkov <ventz@vpetkov.net>
Co-authored-by: James Dumay <jameswdumay@gmail.com>
2026-05-06 21:34:02 +10:00
2026-05-05 11:48:40 +10:00
# Build a Linux ROCm ABI release artifact with an explicit architecture list.
2026-07-29 10:16:23 -04:00
release-build-rocm rocm_arch="gfx90a;gfx942;gfx1100;gfx1101;gfx1102;gfx1103;gfx1151;gfx1200;gfx1201" : release -host -build
@LLAMA_STAGE_AMDGPU_TARGETS= "{{ rocm_arch }}" \
scripts/package-native-runtime.sh --build --backend rocm --target x86_64-unknown-linux-gnu
2026-03-27 21:36:19 +11:00
2026-07-21 21:21:51 -04:00
release-build-rocm-windows rocm_arch="gfx90a;gfx942;gfx1100;gfx1101;gfx1102;gfx1103;gfx1151;gfx1200;gfx1201" :
2026-07-29 10:16:23 -04:00
@powershell -NoProfile -ExecutionPolicy Bypass -File scripts/build-windows.ps1 -Backend rocm -RocmArch "{{ rocm_arch }}" -BuildProfile release -DynamicHost
2026-03-29 08:35:43 +11:00
2026-05-05 11:48:40 +10:00
# Build a Linux Vulkan ABI release artifact.
2026-07-29 10:16:23 -04:00
release-build-vulkan : release -host -build
@scripts/package-native-runtime.sh --build --backend vulkan --target x86_64-unknown-linux-gnu
2026-03-28 11:07:22 +11:00
2026-03-29 08:57:02 +11:00
release-build-vulkan-windows :
2026-07-29 10:16:23 -04:00
@powershell -NoProfile -ExecutionPolicy Bypass -File scripts/build-windows.ps1 -Backend vulkan -BuildProfile release -DynamicHost
2026-03-29 08:35:43 +11:00
2026-05-05 11:48:40 +10:00
# Build the skippy benchmark/debug telemetry collector.
2026-05-10 08:14:22 +10:00
[ u n i x ]
2026-05-18 22:58:00 -04:00
metrics-server-build :
just with-lld cargo build -p metrics-server
2026-05-05 11:48:40 +10:00
2026-05-10 08:14:22 +10:00
[ w i n d o w s ]
2026-05-18 22:58:00 -04:00
metrics-server-build :
@just with-lld cargo build -p metrics-server
2026-05-10 08:14:22 +10:00
2026-05-13 07:10:20 +10:00
# Build the binaries copied into the Skippy WAN Docker lab image.
[ l i n u x ]
skippy-wan-lab-build-bins :
cargo build --release --locked -p skippy-server -p skippy-prompt -p metrics-server -p skippy-model-package
2026-06-23 12:35:27 +10:00
# Build the resumable GGUF conversion/quantization replacement CLI.
[ u n i x ]
skippy-quantize-build :
just with-lld cargo build -p skippy-quantize
[ w i n d o w s ]
skippy-quantize-build :
@just with-lld cargo build -p skippy-quantize
# Build the release binary used in HF conversion/quantization job images.
[ u n i x ]
skippy-quantize-release-build :
just with-lld cargo build --release --locked -p skippy-quantize
[ w i n d o w s ]
skippy-quantize-release-build :
@just with-lld cargo build --release --locked -p skippy-quantize
# Build skippy-quantize as a standalone quantization binary with the pinned
# llama.cpp quantization ABI linked into the executable.
[ u n i x ]
skippy-quantize-standalone-build backend="cpu" :
2026-08-03 17:03:05 +10:00
scripts/prepare-llama.sh pinned
LLAMA_STAGE_BACKEND = "{{ backend }}" LLAMA_STAGE_LINK_MODE = static scripts/build-llama.sh
LLAMA_STAGE_BACKEND = "{{ backend }}" LLAMA_STAGE_LINK_MODE = static just with-lld cargo build -p skippy-quantize --no-default-features
2026-06-23 12:35:27 +10:00
[ u n i x ]
skippy-quantize-standalone-release-build backend="cpu" :
2026-08-03 17:03:05 +10:00
scripts/prepare-llama.sh pinned
LLAMA_STAGE_BACKEND = "{{ backend }}" LLAMA_STAGE_LINK_MODE = static scripts/build-llama.sh
LLAMA_STAGE_BACKEND = "{{ backend }}" LLAMA_STAGE_LINK_MODE = static just with-lld cargo build --release --locked -p skippy-quantize --no-default-features
2026-06-23 12:35:27 +10:00
2026-05-05 11:48:40 +10:00
# Generate a reproducible benchmark corpus for skippy bench tooling.
2026-05-25 00:40:03 +02:00
bench-corpus tier="smoke" *ARGS="" :
2026-05-05 11:48:40 +10:00
scripts/generate-bench-corpus.py "{{ tier }}" { { ARGS } }
# Run skippy family certification checks.
2026-05-18 22:58:00 -04:00
family-certify *ARGS :
just with-lld scripts/family-certify.sh { { ARGS } }
2026-05-05 11:48:40 +10:00
# Run target/draft speculative compatibility checks.
2026-05-18 22:58:00 -04:00
spec-bench target draft *ARGS :
just with-lld env LLAMA_STAGE_BUILD_DIR = ".deps/llama-build/build-stage-abi-static" cargo build -p llama-spec-bench
2026-05-09 18:49:59 +10:00
LLAMA_STAGE_BUILD_DIR = ".deps/llama-build/build-stage-abi-static" target/debug/llama-spec-bench --target-model-path "{{ target }}" --draft-model-path "{{ draft }}" { { ARGS } }
2026-05-05 11:48:40 +10:00
# Smoke a standalone skippy OpenAI frontend stage.
2026-05-18 22:58:00 -04:00
skippy-openai-smoke *ARGS :
just with-lld scripts/skippy-openai-smoke.sh { { ARGS } }
2026-05-05 11:48:40 +10:00
# Run the skippy benchmark/debug telemetry collector.
2026-05-25 00:40:03 +02:00
metrics-server db="/tmp/mesh-metrics.duckdb" http_addr="127.0.0.1 : 18080" otlp_addr ="127.0.0.1:14317" *ARGS ="": metrics -server -build
2026-05-05 11:48:40 +10:00
target/debug/metrics-server serve --db "{{ db }}" --http-addr "{{ http_addr }}" --otlp-grpc-addr "{{ otlp_addr }}" { { ARGS } }
reorganize: add Justfile, move latency benchmarking to subdir, remove notes.md
- Justfile: build, download-model, worker, serve, local, stop, test, diff
- latency-benchmarking/: demo.sh, bench.sh, bench-b2b.sh, latency-proxy.py, measure.py
- notes.md -> latency-benchmarking/README.md (reference for that tooling)
- Scripts updated to resolve llama.cpp from parent dir
2026-02-12 20:16:10 +11:00
# Download the default model (GLM-4.7-Flash Q4_K_M, 17GB)
download-model :
#!/usr/bin/env bash
set -euo pipefail
2026-03-27 18:30:22 +11:00
mkdir -p "{{ models_dir }}"
if [ -f "{{ model }}" ] ; then
echo "Model already exists: {{ model }}"
reorganize: add Justfile, move latency benchmarking to subdir, remove notes.md
- Justfile: build, download-model, worker, serve, local, stop, test, diff
- latency-benchmarking/: demo.sh, bench.sh, bench-b2b.sh, latency-proxy.py, measure.py
- notes.md -> latency-benchmarking/README.md (reference for that tooling)
- Scripts updated to resolve llama.cpp from parent dir
2026-02-12 20:16:10 +11:00
else
echo "Downloading GLM-4.7-Flash Q4_K_M (~17GB)..."
2026-03-27 18:30:22 +11:00
curl -L -o "{{ model }}" \
reorganize: add Justfile, move latency benchmarking to subdir, remove notes.md
- Justfile: build, download-model, worker, serve, local, stop, test, diff
- latency-benchmarking/: demo.sh, bench.sh, bench-b2b.sh, latency-proxy.py, measure.py
- notes.md -> latency-benchmarking/README.md (reference for that tooling)
- Scripts updated to resolve llama.cpp from parent dir
2026-02-12 20:16:10 +11:00
"https://huggingface.co/unsloth/GLM-4.7-Flash-GGUF/resolve/main/GLM-4.7-Flash-Q4_K_M.gguf"
fi
2026-02-13 12:04:34 +11:00
# ── QUIC Mesh ──────────────────────────────────────────────────
2026-07-16 16:05:03 -04:00
mesh_bin := env( "MESH_LLM_BIN" , "target/release/mesh-llm" )
2026-02-13 12:04:34 +11:00
# Prints an invite token for other nodes to join.
mesh-worker gguf=model :
2026-07-16 16:05:03 -04:00
"{{ mesh_bin }}" --model { { gguf } }
2026-02-13 12:04:34 +11:00
2026-05-05 11:48:40 +10:00
# Join an existing mesh and serve through the embedded runtime.
2026-02-16 16:29:06 +11:00
mesh-join join="" port="9337" gguf=model split="" :
2026-02-13 12:04:34 +11:00
#!/usr/bin/env bash
set -euo pipefail
2026-05-05 11:48:40 +10:00
ARGS = "--model {{ gguf }} --port {{ port }}"
2026-03-27 18:30:22 +11:00
if [ -n "{{ join }}" ] ; then
ARGS = " $ARGS --join {{ join }} "
2026-02-13 12:04:34 +11:00
fi
2026-03-27 18:30:22 +11:00
if [ -n "{{ split }}" ] ; then
ARGS = " $ARGS --tensor-split {{ split }} "
2026-02-13 12:04:34 +11:00
fi
2026-07-16 16:05:03 -04:00
exec "{{ mesh_bin }}" $ARGS
2026-02-13 12:04:34 +11:00
2026-07-29 10:16:23 -04:00
# Create a portable product tarball containing the neutral host and default runtime.
bundle output="/tmp/mesh-llm-bundle.tar.gz" : release -build
2026-02-13 12:04:34 +11:00
#!/usr/bin/env bash
set -euo pipefail
2026-07-29 10:16:23 -04:00
staging_dir = " $( mktemp -d) "
trap 'rm -rf "$staging_dir"' EXIT
version = " v $( "{{ mesh_bin }}" --version | awk '{print $NF}' ) "
scripts/package-release.sh " $version " " $staging_dir "
stable_archive = ""
for candidate in " $staging_dir " /mesh-llm-*.tar.gz; do
[ [ -f " $candidate " ] ] || continue
case " $( basename " $candidate " ) " in
mesh-llm-" $version " -*) continue ; ;
esac
if [ [ -n " $stable_archive " ] ] ; then
echo "multiple stable product archives were produced" >& 2
exit 1
fi
stable_archive = " $candidate "
2026-02-13 12:04:34 +11:00
done
2026-07-29 10:16:23 -04:00
if [ [ -z " $stable_archive " ] ] ; then
echo "product packaging did not produce a stable archive" >& 2
exit 1
fi
mkdir -p " $( dirname "{{ output }}" ) "
cp " $stable_archive " "{{ output }}"
cp " $stable_archive .sha256 " "{{ output }}.sha256"
echo " Bundle: {{ output }} ( $( du -sh "{{ output }}" | cut -f1) ) "
2026-03-27 18:30:22 +11:00
# Create release archive(s) for the current platform.
# `version` should be a tag like v0.30.0.
release-bundle version output="dist" :
@scripts/package-release.sh "{{ version }}" "{{ output }}"
2026-02-13 12:04:34 +11:00
2026-05-29 17:20:36 -04:00
# Create a Linux aarch64 CPU release archive on a native aarch64 runner.
release-bundle-aarch64 version output="dist" :
2026-04-14 02:57:38 -04:00
@scripts/package-release.sh "{{ version }}" "{{ output }}"
2026-05-29 17:20:36 -04:00
# Create a Linux aarch64 CUDA release archive on a native aarch64 runner.
release-bundle-aarch64-cuda version output="dist" :
MESH_RELEASE_ARCH = aarch64 MESH_RELEASE_FLAVOR = cuda scripts/package-release.sh "{{ version }}" "{{ output }}"
2026-04-14 02:57:38 -04:00
# Run repo-level release-target consistency checks.
[ u n i x ]
2026-05-18 22:58:00 -04:00
check-release :
just with-lld cargo run -p xtask -- repo-consistency release-targets
2026-04-14 02:57:38 -04:00
[ w i n d o w s ]
2026-05-18 22:58:00 -04:00
check-release :
@just with-lld cargo run -p xtask -- repo-consistency release-targets
2026-04-14 02:57:38 -04:00
2026-03-29 08:57:02 +11:00
release-bundle-windows version output="dist" :
2026-07-29 10:16:23 -04:00
@powershell -NoProfile -ExecutionPolicy Bypass -File scripts/package-release.ps1 -Version "{{ version }}" -OutputDir "{{ output }}"
2026-03-29 08:35:43 +11:00
2026-03-27 20:51:20 +11:00
# Create Linux CUDA release archive(s).
release-bundle-cuda version output="dist" :
MESH_RELEASE_FLAVOR = cuda scripts/package-release.sh "{{ version }}" "{{ output }}"
2026-03-29 08:57:02 +11:00
release-bundle-cuda-windows version output="dist" :
2026-07-29 10:16:23 -04:00
@powershell -NoProfile -ExecutionPolicy Bypass -File scripts/package-release.ps1 -Version "{{ version }}" -OutputDir "{{ output }}" -Flavor cuda
2026-03-29 08:35:43 +11:00
2026-04-09 21:08:38 -04:00
# Create Linux ROCm release archive(s).
release-bundle-rocm version output="dist" :
2026-03-27 21:36:19 +11:00
MESH_RELEASE_FLAVOR = rocm scripts/package-release.sh "{{ version }}" "{{ output }}"
2026-04-09 21:08:38 -04:00
release-bundle-rocm-windows version output="dist" :
2026-07-29 10:16:23 -04:00
@powershell -NoProfile -ExecutionPolicy Bypass -File scripts/package-release.ps1 -Version "{{ version }}" -OutputDir "{{ output }}" -Flavor rocm
2026-03-29 08:35:43 +11:00
2026-03-28 11:07:22 +11:00
# Create Linux Vulkan release archive(s).
release-bundle-vulkan version output="dist" :
MESH_RELEASE_FLAVOR = vulkan scripts/package-release.sh "{{ version }}" "{{ output }}"
2026-03-29 08:57:02 +11:00
release-bundle-vulkan-windows version output="dist" :
2026-07-29 10:16:23 -04:00
@powershell -NoProfile -ExecutionPolicy Bypass -File scripts/package-release.ps1 -Version "{{ version }}" -OutputDir "{{ output }}" -Flavor vulkan
2026-02-13 12:04:34 +11:00
2026-05-07 21:25:40 -04:00
# Run the UI dev server with Vite HMR, proxying /api to mesh-llm (default: http://127.0.0.1:3131)
2026-02-25 17:06:42 +11:00
ui-dev api="http : //127.0.0.1:3131" port ="5173":
#!/usr/bin/env bash
set -euo pipefail
2026-03-27 18:30:22 +11:00
cd "{{ ui_dir }}"
2026-05-07 21:25:40 -04:00
MESH_UI_API_ORIGIN = "{{ api }}" VITE_API_URL = "{{ api }}" pnpm run dev -- --host 0.0.0.0 --port { { port } }
# Run the UI dev server proxying to the public meshllm.cloud API
2026-06-10 21:54:54 -04:00
ui-dev-public : (ui -dev "https ://public .meshllm .cloud ")
2026-02-25 17:06:42 +11:00
2026-06-10 05:18:25 -04:00
# Build the public website into docs/ for static hosting.
website-build :
cd "{{ website_dir }}" && npm run build
# Run the public website dev server on port 8765.
website-dev :
cd "{{ website_dir }}" && npm run dev
2026-04-08 12:29:40 -04:00
2026-06-10 05:18:25 -04:00
# Remove generated public website output while preserving docs/ source markdown.
website-clean :
cd "{{ website_dir }}" && npm run clean
2026-05-07 18:14:09 -04:00
2026-04-18 23:16:09 -04:00
# Run UI unit tests (vitest)
ui-test :
2026-05-07 21:25:40 -04:00
cd "{{ ui_dir }}" && pnpm test
# ── Full Validation Gate ───────────────────────────────────────
2026-07-16 16:05:03 -04:00
# Run all checks: repo consistency, Rust tests, author exemplars, fmt, clippy, UI/docs builds, and E2E smoke.
2026-05-18 22:58:00 -04:00
test-all :
2026-05-07 21:25:40 -04:00
#!/usr/bin/env bash
set -euo pipefail
feat(runtime): add daemon model lifecycle reconciliation (#1082)
* Add daemon-managed runtime model lifecycle
Introduce persistent runtime lifecycle reconciliation with authenticated owner controls, profile-aware load, unload, ensure, and drain semantics, activity-based admission and priority policy, and additive gossip/protocol support.
Expose the lifecycle through config, CLI, UI, and management APIs; consolidate shared owner-control protocol handling; and add cross-platform build and QA coverage for CUDA setup, mixed versions, process teardown, and SDK/platform paths.
2026-07-27 19:37:50 -04:00
echo "=== 0/11 Test-all rust crate coverage preflight ==="
just with-lld cargo run -p xtask -- repo-consistency test-all-rust-crate-coverage
2026-07-22 14:18:31 -04:00
# A full workspace gate otherwise leaves hundreds of incompatible
# incremental feature graphs behind. CI already builds non-incrementally;
# use the same bounded-disk behavior here unless explicitly overridden.
export CARGO_INCREMENTAL = " ${ CARGO_INCREMENTAL :- 0 } "
dynamic_target_dir = " ${ MESH_TEST_ALL_DYNAMIC_TARGET_DIR :- $PWD /target/test-all-dynamic } "
2026-05-12 21:19:41 +10:00
native_backend = " ${ LLAMA_STAGE_BACKEND :- ${ SKIPPY_LLAMA_BACKEND :- ${ LLAMA_BACKEND :- } } } "
if [ [ -z " $native_backend " ] ] ; then
case " $( uname -s) " in
Darwin) native_backend = "metal" ; ;
*) native_backend = "cpu" ; ;
esac
fi
export LLAMA_STAGE_BACKEND = " $native_backend "
if [ [ -z " ${ LLAMA_STAGE_BUILD_DIR :- } " ] ] ; then
LLAMA_STAGE_BUILD_DIR = " $( scripts/build-llama.sh --print-build-dir) "
export LLAMA_STAGE_BUILD_DIR
2026-05-07 21:25:40 -04:00
fi
2026-05-12 21:19:41 +10:00
echo " === Native llama.cpp ABI ( $LLAMA_STAGE_BACKEND ) === "
echo " Build dir: $LLAMA_STAGE_BUILD_DIR "
scripts/prepare-llama.sh
scripts/build-llama.sh
echo ""
2026-05-07 21:25:40 -04:00
# Each UI step runs in a subshell so cd doesn't leak between steps.
feat(runtime): add daemon model lifecycle reconciliation (#1082)
* Add daemon-managed runtime model lifecycle
Introduce persistent runtime lifecycle reconciliation with authenticated owner controls, profile-aware load, unload, ensure, and drain semantics, activity-based admission and priority policy, and additive gossip/protocol support.
Expose the lifecycle through config, CLI, UI, and management APIs; consolidate shared owner-control protocol handling; and add cross-platform build and QA coverage for CUDA setup, mixed versions, process teardown, and SDK/platform paths.
2026-07-27 19:37:50 -04:00
echo "=== 1/11 Repo consistency ==="
2026-05-25 01:44:59 -04:00
just with-lld cargo run -p xtask -- repo-consistency ci-crate-lists
2026-07-16 16:05:03 -04:00
just with-lld cargo run -p xtask -- repo-consistency publish-crates
2026-05-25 01:44:59 -04:00
echo ""
feat(runtime): add daemon model lifecycle reconciliation (#1082)
* Add daemon-managed runtime model lifecycle
Introduce persistent runtime lifecycle reconciliation with authenticated owner controls, profile-aware load, unload, ensure, and drain semantics, activity-based admission and priority policy, and additive gossip/protocol support.
Expose the lifecycle through config, CLI, UI, and management APIs; consolidate shared owner-control protocol handling; and add cross-platform build and QA coverage for CUDA setup, mixed versions, process teardown, and SDK/platform paths.
2026-07-27 19:37:50 -04:00
echo "=== 2/11 Rust format check ==="
2026-05-18 22:58:00 -04:00
just with-lld cargo fmt --all -- --check
2026-05-07 21:25:40 -04:00
echo ""
2026-07-29 10:16:23 -04:00
echo "=== 3/11 GPU bench crate check ==="
just with-lld cargo check -p mesh-llm-gpu-bench
2026-05-26 18:00:06 -04:00
echo ""
feat(runtime): add daemon model lifecycle reconciliation (#1082)
* Add daemon-managed runtime model lifecycle
Introduce persistent runtime lifecycle reconciliation with authenticated owner controls, profile-aware load, unload, ensure, and drain semantics, activity-based admission and priority policy, and additive gossip/protocol support.
Expose the lifecycle through config, CLI, UI, and management APIs; consolidate shared owner-control protocol handling; and add cross-platform build and QA coverage for CUDA setup, mixed versions, process teardown, and SDK/platform paths.
2026-07-27 19:37:50 -04:00
echo "=== 4-5/11 Rust validation ==="
2026-07-22 14:18:31 -04:00
# Keep Clippy and tests adjacent for each compatible feature graph. Switching
# dynamic -> static -> dynamic -> static forces Cargo to relink both graphs.
echo "--- Dynamic-runtime bindings: Clippy ---"
CARGO_TARGET_DIR = " $dynamic_target_dir " just with-lld cargo clippy \
-p mesh-llm-ffi \
-p mesh-llm-nodejs \
-p skippy-ffi \
-p skippy-quantize \
--all-targets -- -D warnings
echo "--- Dynamic-runtime bindings: tests ---"
CARGO_TARGET_DIR = " $dynamic_target_dir " just with-lld cargo test \
-p mesh-llm-ffi \
-p mesh-llm-nodejs \
-p skippy-ffi \
-p skippy-quantize
echo "--- Static development workspace: Clippy ---"
just with-lld cargo clippy --workspace --all-targets \
--exclude mesh-llm-ffi \
--exclude mesh-llm-nodejs \
--exclude skippy-ffi \
--exclude skippy-quantize \
-- -D warnings
echo "--- Static development workspace: tests ---"
just with-lld cargo test --workspace \
--exclude mesh-llm-ffi \
--exclude mesh-llm-nodejs \
--exclude skippy-ffi \
2026-08-05 03:22:46 +10:00
--exclude skippy-quantize \
--exclude skippy-runtime \
--exclude skippy-server
echo "--- Static Skippy runtime tests ---"
just with-lld cargo test --package skippy-runtime --no-default-features --lib
echo "--- Static Skippy server tests ---"
just with-lld cargo test --package skippy-server --no-default-features --lib
2026-05-07 21:25:40 -04:00
echo ""
feat(runtime): add daemon model lifecycle reconciliation (#1082)
* Add daemon-managed runtime model lifecycle
Introduce persistent runtime lifecycle reconciliation with authenticated owner controls, profile-aware load, unload, ensure, and drain semantics, activity-based admission and priority policy, and additive gossip/protocol support.
Expose the lifecycle through config, CLI, UI, and management APIs; consolidate shared owner-control protocol handling; and add cross-platform build and QA coverage for CUDA setup, mixed versions, process teardown, and SDK/platform paths.
2026-07-27 19:37:50 -04:00
echo "=== 6/11 Plugin author exemplar ==="
2026-07-16 16:05:03 -04:00
just with-lld cargo run --quiet --manifest-path docs/plugins/exemplars/web-ui/Cargo.toml -- --print-package-manifest > target/web-ui-exemplar-manifest.json
diff -u <( jq -S . docs/plugins/exemplars/web-ui/plugin.package.json) <( jq -S . target/web-ui-exemplar-manifest.json)
node --check docs/plugins/exemplars/web-ui/bundle/register-mesh-plugin-ui.js
( cd "{{ ui_dir }}" && pnpm exec tsc --ignoreConfig --noEmit --target ES2022 --module ESNext --moduleResolution Bundler --lib ES2022,DOM ../../docs/plugins/exemplars/web-ui/bundle/register-mesh-plugin-ui.ts)
echo ""
feat(runtime): add daemon model lifecycle reconciliation (#1082)
* Add daemon-managed runtime model lifecycle
Introduce persistent runtime lifecycle reconciliation with authenticated owner controls, profile-aware load, unload, ensure, and drain semantics, activity-based admission and priority policy, and additive gossip/protocol support.
Expose the lifecycle through config, CLI, UI, and management APIs; consolidate shared owner-control protocol handling; and add cross-platform build and QA coverage for CUDA setup, mixed versions, process teardown, and SDK/platform paths.
2026-07-27 19:37:50 -04:00
echo "=== 7-10/11 Parallel portable checks and builds ==="
2026-07-22 14:18:31 -04:00
scripts/test-portable.sh
2026-07-16 16:05:03 -04:00
echo ""
feat(runtime): add daemon model lifecycle reconciliation (#1082)
* Add daemon-managed runtime model lifecycle
Introduce persistent runtime lifecycle reconciliation with authenticated owner controls, profile-aware load, unload, ensure, and drain semantics, activity-based admission and priority policy, and additive gossip/protocol support.
Expose the lifecycle through config, CLI, UI, and management APIs; consolidate shared owner-control protocol handling; and add cross-platform build and QA coverage for CUDA setup, mixed versions, process teardown, and SDK/platform paths.
2026-07-27 19:37:50 -04:00
echo "=== 11/11 E2E smoke tests (Playwright) ==="
2026-07-22 14:18:31 -04:00
( cd "{{ ui_dir }}" && pnpm run test:e2e)
2026-05-07 21:25:40 -04:00
echo ""
echo "All checks passed."
2026-04-18 23:16:09 -04:00
docs: update all docs for --client mode, B2B, current state
- README.md: simplified, added lite client section, node roles table,
removed stale configs, current benchmarks only
- mesh-inference/README.md: added --client usage with curl examples,
all options table, B2B and lite client in how-it-works
- mesh-inference/DESIGN.md: rewritten for current architecture —
4 stream types, B2B flow, lite client, accurate file descriptions
- PLAN.md: trimmed to historical reference — removed stale next-steps
and 'iroh is unsuitable' framing, kept benchmarks and design decisions
- Justfile: added mesh-client target
2026-02-13 14:43:12 +11:00
# Start a lite client — no GPU, no model, just a local HTTP proxy to the mesh host.
2026-03-27 18:30:22 +11:00
2026-02-17 19:47:04 +11:00
# Only needs the mesh-llm binary (no llama.cpp binaries or model).
2026-07-16 16:05:03 -04:00
mesh-client join="" port="9337" console="3131" config="" :
#!/usr/bin/env bash
set -euo pipefail
args = ( client --port "{{ port }}" --console "{{ console }}" )
if [ [ -n "{{ join }}" ] ] ; then
args += ( --join "{{ join }}" )
fi
if [ [ -n "{{ config }}" ] ] ; then
args += ( --config "{{ config }}" )
fi
"{{ mesh_bin }}" " ${ args [@] } "
docs: update all docs for --client mode, B2B, current state
- README.md: simplified, added lite client section, node roles table,
removed stale configs, current benchmarks only
- mesh-inference/README.md: added --client usage with curl examples,
all options table, B2B and lite client in how-it-works
- mesh-inference/DESIGN.md: rewritten for current architecture —
4 stream types, B2B flow, lite client, accurate file descriptions
- PLAN.md: trimmed to historical reference — removed stale next-steps
and 'iroh is unsuitable' framing, kept benchmarks and design decisions
- Justfile: added mesh-client target
2026-02-13 14:43:12 +11:00
2026-03-04 15:47:52 -05:00
# Build and auto-join a mesh (discover via Nostr)
auto : build
2026-07-16 16:05:03 -04:00
"{{ mesh_bin }}" --auto
2026-03-04 15:47:52 -05:00
2026-02-13 12:04:34 +11:00
# ── Utilities ──────────────────────────────────────────────────
2026-04-26 07:55:48 +10:00
# Update both tracked llama.cpp pin files from the prepared checkout.
llama-update-pin :
scripts/update-llama-pin.sh
# Render a Markdown summary for a llama.cpp upstream pin change.
llama-summary old new :
scripts/summarize-llama-upstream.sh "{{ old }}" "{{ new }}"
2026-05-10 08:14:22 +10:00
# Clean Rust, llama.cpp, and UI build artifacts.
[ u n i x ]
clean :
#!/usr/bin/env bash
set -euo pipefail
rm -rf \
target \
.deps/llama.cpp/build-stage-abi-* \
.deps/llama-build/build-stage-abi-* \
"{{ ui_dir }}/node_modules" \
"{{ ui_dir }}/dist"
echo "Cleaned Rust target, llama.cpp build dirs, and UI artifacts"
[ w i n d o w s ]
clean :
@powershell -NoProfile -ExecutionPolicy Bypass -Command "Remove-Item -Recurse -Force target,'.deps/llama.cpp/build-stage-abi-*','.deps/llama-build/build-stage-abi-*','{{ ui_dir }}/node_modules','{{ ui_dir }}/dist' -ErrorAction SilentlyContinue"
echo "Cleaned Rust target, llama.cpp build dirs, and UI artifacts"
2026-05-07 21:25:40 -04:00
# Clean UI build artifacts (node_modules, dist). Fixes stale pnpm state.
2026-04-08 09:37:15 +10:00
[ u n i x ]
2026-05-07 21:25:40 -04:00
ui-clean :
2026-04-08 09:37:15 +10:00
cd "{{ ui_dir }}" && rm -rf node_modules dist
echo "Cleaned UI: node_modules + dist removed"
[ w i n d o w s ]
2026-05-07 21:25:40 -04:00
ui-clean :
2026-04-08 09:37:15 +10:00
@powershell -NoProfile -ExecutionPolicy Bypass -Command "Set-Location '{{ ui_dir }}'; Remove-Item -Recurse -Force node_modules,dist -ErrorAction SilentlyContinue"
echo "Cleaned UI: node_modules + dist removed"
2026-05-05 11:48:40 +10:00
# Stop mesh-llm processes
reorganize: add Justfile, move latency benchmarking to subdir, remove notes.md
- Justfile: build, download-model, worker, serve, local, stop, test, diff
- latency-benchmarking/: demo.sh, bench.sh, bench-b2b.sh, latency-proxy.py, measure.py
- notes.md -> latency-benchmarking/README.md (reference for that tooling)
- Scripts updated to resolve llama.cpp from parent dir
2026-02-12 20:16:10 +11:00
stop :
2026-02-17 19:47:04 +11:00
pkill -f "mesh-llm" 2>/dev/null || true
reorganize: add Justfile, move latency benchmarking to subdir, remove notes.md
- Justfile: build, download-model, worker, serve, local, stop, test, diff
- latency-benchmarking/: demo.sh, bench.sh, bench-b2b.sh, latency-proxy.py, measure.py
- notes.md -> latency-benchmarking/README.md (reference for that tooling)
- Scripts updated to resolve llama.cpp from parent dir
2026-02-12 20:16:10 +11:00
echo "Stopped"
2026-02-13 12:04:34 +11:00
# Quick test inference (works with any running server on 8080 or 8090)
2026-02-16 16:29:06 +11:00
test port="9337" :
2026-03-27 18:30:22 +11:00
curl -s http://localhost:{ { port } } /v1/chat/completions \
reorganize: add Justfile, move latency benchmarking to subdir, remove notes.md
- Justfile: build, download-model, worker, serve, local, stop, test, diff
- latency-benchmarking/: demo.sh, bench.sh, bench-b2b.sh, latency-proxy.py, measure.py
- notes.md -> latency-benchmarking/README.md (reference for that tooling)
- Scripts updated to resolve llama.cpp from parent dir
2026-02-12 20:16:10 +11:00
-H 'Content-Type: application/json' \
2026-02-13 12:04:34 +11:00
-d '{"model":"test","messages":[{"role":"user","content":"Hello! Write a haiku about distributed computing."}],"max_tokens":50}' \
| python3 -c "import sys,json; d=json.load(sys.stdin); t=d['timings']; print(d['choices'][0]['message'].get('content','')[:200]); print(f\" prompt: {t['prompt_per_second']:.1f} tok/s gen: {t['predicted_per_second']:.1f} tok/s ({t['predicted_n']} tok)\")"
reorganize: add Justfile, move latency benchmarking to subdir, remove notes.md
- Justfile: build, download-model, worker, serve, local, stop, test, diff
- latency-benchmarking/: demo.sh, bench.sh, bench-b2b.sh, latency-proxy.py, measure.py
- notes.md -> latency-benchmarking/README.md (reference for that tooling)
- Scripts updated to resolve llama.cpp from parent dir
2026-02-12 20:16:10 +11:00
2026-05-05 11:48:40 +10:00
# Show the local llama.cpp ABI patch queue
reorganize: add Justfile, move latency benchmarking to subdir, remove notes.md
- Justfile: build, download-model, worker, serve, local, stop, test, diff
- latency-benchmarking/: demo.sh, bench.sh, bench-b2b.sh, latency-proxy.py, measure.py
- notes.md -> latency-benchmarking/README.md (reference for that tooling)
- Scripts updated to resolve llama.cpp from parent dir
2026-02-12 20:16:10 +11:00
diff :
2026-04-25 18:57:47 +10:00
ls -1 third_party/llama.cpp/patches
2026-04-12 16:17:59 -04:00
2026-05-05 11:48:40 +10:00
# Build the client-only Docker image
2026-04-12 16:17:59 -04:00
[ u n i x ]
docker-build-client tag="mesh-llm : client ":
DOCKER_BUILDKIT = 1 docker build -f docker/Dockerfile.client -t { { tag } } .
[ w i n d o w s ]
docker-build-client tag="mesh-llm : client ":
@powershell -NoProfile -ExecutionPolicy Bypass -Command " $env :DOCKER_BUILDKIT='1'; docker build -f docker/Dockerfile.client -t '{{ tag }}' . "
# Run the client console image locally
docker-run-client tag="mesh-llm : client ":
docker run --rm -p 3131:3131 -p 9337:9337 -e APP_MODE = console { { tag } }