Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
214 changes: 80 additions & 134 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,14 @@ jobs:
build_recipe: release-build
bundle_recipe: release-bundle
backend: metal
target: aarch64-apple-darwin
- name: Linux x86_64 CPU
os: ubuntu-24.04
artifact_name: release-linux
build_recipe: release-build
bundle_recipe: release-bundle
backend: cpu
target: x86_64-unknown-linux-gnu
env:
LLAMA_STAGE_BACKEND: ${{ matrix.backend }}
steps:
Expand Down Expand Up @@ -142,6 +144,12 @@ jobs:
printf '%s' "$RELEASE_ATTESTATION_PUBLIC_KEY" > "$MESH_RELEASE_ATTESTATION_PUBLIC_KEY_FILE"
just --shell bash --shell-arg -c ${{ matrix.build_recipe }}
just --shell bash --shell-arg -c ${{ matrix.bundle_recipe }} "$RELEASE_TAG" dist
scripts/package-native-runtime.sh \
--build \
--backend "${{ matrix.backend }}" \
--target "${{ matrix.target }}" \
--out dist
scripts/verify-native-runtime-package.sh dist/meshllm-native-runtime-*.tar.gz

- name: Upload release bundle
uses: actions/upload-artifact@v6
Expand All @@ -152,11 +160,13 @@ jobs:

- name: Upload Linux smoke binary
if: matrix.artifact_name == 'release-linux'
env:
RELEASE_TAG: ${{ needs.metadata.outputs.tag }}
run: |
set -euo pipefail
tmp_dir="$(mktemp -d)"
trap 'rm -rf "$tmp_dir"' EXIT
tar -xzf dist/mesh-llm-x86_64-unknown-linux-gnu.tar.gz -C "$tmp_dir"
tar -xzf "dist/mesh-llm-${RELEASE_TAG}-x86_64-unknown-linux-gnu.tar.gz" -C "$tmp_dir"
cp "$tmp_dir/mesh-bundle/mesh-llm" dist/mesh-llm

- name: Upload Linux smoke binary artifact
Expand All @@ -179,134 +189,6 @@ jobs:
secrets:
HF_TOKEN: ${{ secrets.HF_TOKEN }}

build_native_sdk_runtime:
name: Build native SDK runtime ${{ matrix.name }}
needs: metadata
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- name: macOS aarch64 Metal
os: macos-15
backend: metal
target: aarch64-apple-darwin
artifact_suffix: darwin-aarch64-metal
- name: Linux x86_64 CPU
os: ubuntu-24.04
backend: cpu
target: x86_64-unknown-linux-gnu
artifact_suffix: linux-x86_64-cpu
env:
LLAMA_STAGE_BACKEND: ${{ matrix.backend }}
MESH_NATIVE_SDK_TARGET: ${{ matrix.target }}
steps:
- uses: actions/checkout@v5

- uses: dtolnay/rust-toolchain@stable

- uses: mozilla-actions/sccache-action@v0.0.9

- name: Install Linux dependencies
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y build-essential cmake ninja-build pkg-config libssl-dev libdbus-1-dev curl lld

- name: Install macOS dependencies
if: runner.os == 'macOS'
run: brew install cmake ninja lld

- name: Prepare dispatched release version
if: github.event_name == 'workflow_dispatch'
env:
RELEASE_TAG: ${{ needs.metadata.outputs.tag }}
run: scripts/release-version.sh "$RELEASE_TAG"

- name: Package native SDK runtime
run: |
scripts/package-native-sdk.sh \
--build \
--backend "${{ matrix.backend }}" \
--target "${{ matrix.target }}" \
--out dist/native-sdk

- name: Verify native SDK runtime artifact
run: scripts/verify-native-sdk-package.sh dist/native-sdk/*.tar.gz

- name: Package native SDK runtime crate
run: scripts/package-native-sdk-crate.sh --out dist/native-sdk-crates dist/native-sdk/*.tar.gz

- name: Upload native SDK runtime
uses: actions/upload-artifact@v6
with:
name: release-native-sdk-${{ matrix.artifact_suffix }}
path: |
dist/native-sdk/*.tar.gz
dist/native-sdk/*.sha256
dist/native-sdk-crates/*/target/package/*.crate
if-no-files-found: error

build_native_runtime:
name: Build native runtime ${{ matrix.name }}
needs: metadata
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- name: macOS aarch64 Metal
os: macos-15
backend: metal
target: aarch64-apple-darwin
artifact_suffix: darwin-aarch64-metal
- name: Linux x86_64 CPU
os: ubuntu-24.04
backend: cpu
target: x86_64-unknown-linux-gnu
artifact_suffix: linux-x86_64-cpu
env:
LLAMA_STAGE_BACKEND: ${{ matrix.backend }}
MESH_NATIVE_RUNTIME_TARGET: ${{ matrix.target }}
steps:
- uses: actions/checkout@v5

- uses: dtolnay/rust-toolchain@stable

- uses: mozilla-actions/sccache-action@v0.0.9

- name: Install Linux dependencies
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y build-essential cmake ninja-build pkg-config libssl-dev libdbus-1-dev curl lld

- name: Install macOS dependencies
if: runner.os == 'macOS'
run: brew install cmake ninja lld

- name: Prepare dispatched release version
if: github.event_name == 'workflow_dispatch'
env:
RELEASE_TAG: ${{ needs.metadata.outputs.tag }}
run: scripts/release-version.sh "$RELEASE_TAG"

- name: Package native runtime
run: |
scripts/package-native-runtime.sh \
--build \
--backend "${{ matrix.backend }}" \
--target "${{ matrix.target }}" \
--out dist/native-runtimes

- name: Verify native runtime artifact
run: scripts/verify-native-runtime-package.sh dist/native-runtimes/*.tar.gz

- name: Upload native runtime
uses: actions/upload-artifact@v6
with:
name: release-native-runtime-${{ matrix.artifact_suffix }}
path: |
dist/native-runtimes/*.tar.gz
dist/native-runtimes/*.sha256
if-no-files-found: error

build_swift_sdk_artifact:
name: Build Swift SDK XCFramework
needs: metadata
Expand Down Expand Up @@ -428,6 +310,12 @@ jobs:
printf '%s' "$RELEASE_ATTESTATION_PUBLIC_KEY" > "$MESH_RELEASE_ATTESTATION_PUBLIC_KEY_FILE"
just --shell bash --shell-arg -c release-build-aarch64
just --shell bash --shell-arg -c release-bundle-aarch64 "$RELEASE_TAG" dist
scripts/package-native-runtime.sh \
--build \
--backend cpu \
--target aarch64-unknown-linux-gnu \
--out dist
scripts/verify-native-runtime-package.sh dist/meshllm-native-runtime-*.tar.gz
- uses: actions/upload-artifact@v6
with:
name: release-linux-arm64
Expand Down Expand Up @@ -488,6 +376,14 @@ jobs:
run: |
just --shell bash --shell-arg -c release-build-aarch64-cuda
just --shell bash --shell-arg -c release-bundle-aarch64-cuda "$RELEASE_TAG" dist
export MESH_LLM_CUDA_TOOLKIT_MAJOR="${MESH_CUDA_VERSION%%.*}"
export LLAMA_STAGE_CUDA_ARCHITECTURES="$(if [[ "${MESH_CUDA_VERSION:-}" == 13.* ]]; then echo '75;80;86;87;89;90;110'; else echo '75;80;86;87;89;90'; fi)"
scripts/package-native-runtime.sh \
--build \
--backend cuda \
--target aarch64-unknown-linux-gnu \
--out dist
scripts/verify-native-runtime-package.sh dist/meshllm-native-runtime-*.tar.gz
- uses: actions/upload-artifact@v6
with:
name: release-linux-aarch64-cuda-${{ matrix.cuda_version }}
Expand Down Expand Up @@ -553,6 +449,14 @@ jobs:
printf '%s' "$RELEASE_ATTESTATION_PUBLIC_KEY" > "$MESH_RELEASE_ATTESTATION_PUBLIC_KEY_FILE"
just --shell bash --shell-arg -c release-build-cuda
just --shell bash --shell-arg -c release-bundle-cuda "$RELEASE_TAG" dist
export MESH_LLM_CUDA_TOOLKIT_MAJOR="${MESH_CUDA_VERSION%%.*}"
export LLAMA_STAGE_CUDA_ARCHITECTURES="$(if [[ "${MESH_CUDA_VERSION:-}" == 13.* ]]; then echo '75;80;86;87;89;90;100;103;120;121'; else echo '75;80;86;87;89;90'; fi)"
scripts/package-native-runtime.sh \
--build \
--backend cuda \
--target x86_64-unknown-linux-gnu \
--out dist
scripts/verify-native-runtime-package.sh dist/meshllm-native-runtime-*.tar.gz
- uses: actions/upload-artifact@v6
with:
name: release-linux-cuda-${{ matrix.cuda_version }}
Expand Down Expand Up @@ -615,6 +519,14 @@ jobs:
printf '%s' "$RELEASE_ATTESTATION_PUBLIC_KEY" > "$MESH_RELEASE_ATTESTATION_PUBLIC_KEY_FILE"
just --shell bash --shell-arg -c release-build-rocm
just --shell bash --shell-arg -c release-bundle-rocm "$RELEASE_TAG" dist
export MESH_LLM_ROCM_VERSION=7.0
export LLAMA_STAGE_AMDGPU_TARGETS='gfx90a;gfx942;gfx1100;gfx1101;gfx1102;gfx1200;gfx1201'
scripts/package-native-runtime.sh \
--build \
--backend rocm \
--target x86_64-unknown-linux-gnu \
--out dist
scripts/verify-native-runtime-package.sh dist/meshllm-native-runtime-*.tar.gz
- uses: actions/upload-artifact@v6
with:
name: release-linux-rocm
Expand Down Expand Up @@ -661,6 +573,12 @@ jobs:
printf '%s' "$RELEASE_ATTESTATION_PUBLIC_KEY" > "$MESH_RELEASE_ATTESTATION_PUBLIC_KEY_FILE"
just --shell bash --shell-arg -c release-build-vulkan
just --shell bash --shell-arg -c release-bundle-vulkan "$RELEASE_TAG" dist
scripts/package-native-runtime.sh \
--build \
--backend vulkan \
--target x86_64-unknown-linux-gnu \
--out dist
scripts/verify-native-runtime-package.sh dist/meshllm-native-runtime-*.tar.gz
- uses: actions/upload-artifact@v6
with:
name: release-linux-vulkan
Expand Down Expand Up @@ -708,6 +626,15 @@ jobs:
Set-Content -Path $env:MESH_RELEASE_ATTESTATION_PUBLIC_KEY_FILE -Value $env:RELEASE_ATTESTATION_PUBLIC_KEY -NoNewline
just release-build-windows
just release-bundle-windows "$env:RELEASE_TAG" dist
- name: Package Windows CPU native runtime
shell: bash
run: |
scripts/package-native-runtime.sh \
--build \
--backend cpu \
--target x86_64-pc-windows-msvc \
--out dist
scripts/verify-native-runtime-package.sh dist/meshllm-native-runtime-*.tar.gz
- uses: actions/upload-artifact@v6
with:
name: release-windows
Expand All @@ -725,8 +652,8 @@ jobs:
# `choco install cuda` (used previously via install-windows-sdk.ps1)
# pulls latest = CUDA 13.2, which deterministically crashes sccache
# on nvcc output (see mozilla/sccache#2470). CI pins to the same
# version via Jimver/cuda-toolkit; mirror that here.
WINDOWS_CUDA_VERSION: ${{ vars.CUDA_VERSION || '12.9.2' }}
# version via Jimver/cuda-toolkit; use a version available in that action.
WINDOWS_CUDA_VERSION: ${{ vars.WINDOWS_CUDA_VERSION || '12.9.1' }}
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -814,6 +741,27 @@ jobs:
Set-Content -Path $env:MESH_RELEASE_ATTESTATION_PUBLIC_KEY_FILE -Value $env:RELEASE_ATTESTATION_PUBLIC_KEY -NoNewline
just ${{ matrix.build_recipe }}
just ${{ matrix.bundle_recipe }} "$env:RELEASE_TAG" dist
- name: Package Windows native runtime
shell: bash
env:
BACKEND: ${{ matrix.backend }}
run: |
case "$BACKEND" in
cuda)
export MESH_LLM_CUDA_TOOLKIT_MAJOR="${WINDOWS_CUDA_VERSION%%.*}"
export LLAMA_STAGE_CUDA_ARCHITECTURES='75;80;86;87;89;90'
;;
rocm)
export MESH_LLM_ROCM_VERSION=7.0
export LLAMA_STAGE_AMDGPU_TARGETS='gfx90a;gfx942;gfx1100;gfx1101;gfx1102;gfx1200;gfx1201'
;;
esac
scripts/package-native-runtime.sh \
--build \
--backend "$BACKEND" \
--target x86_64-pc-windows-msvc \
--out dist
scripts/verify-native-runtime-package.sh dist/meshllm-native-runtime-*.tar.gz
- uses: actions/upload-artifact@v6
with:
name: ${{ matrix.artifact_name }}
Expand All @@ -826,8 +774,6 @@ jobs:
- metadata
- build
- inference_smoke_tests
- build_native_sdk_runtime
- build_native_runtime
- build_swift_sdk_artifact
- build_linux_arm64
- build_linux_aarch64_cuda
Expand All @@ -836,7 +782,7 @@ jobs:
- build_linux_vulkan
- build_windows_cpu
- build_windows_gpu
if: ${{ always() && needs.metadata.result == 'success' && needs.metadata.outputs.canary != 'true' && needs.build.result == 'success' && needs.inference_smoke_tests.result == 'success' && needs.build_native_sdk_runtime.result == 'success' && needs.build_native_runtime.result == 'success' && needs.build_swift_sdk_artifact.result == 'success' && needs.build_linux_arm64.result == 'success' && (needs.build_linux_aarch64_cuda.result == 'success' || needs.build_linux_aarch64_cuda.result == 'skipped') && (needs.build_linux_cuda.result == 'success' || needs.build_linux_cuda.result == 'skipped') && (needs.build_linux_rocm.result == 'success' || needs.build_linux_rocm.result == 'skipped') && (needs.build_linux_vulkan.result == 'success' || needs.build_linux_vulkan.result == 'skipped') && needs.build_windows_cpu.result == 'success' && (needs.build_windows_gpu.result == 'success' || needs.build_windows_gpu.result == 'skipped') }}
if: ${{ always() && needs.metadata.result == 'success' && needs.metadata.outputs.canary != 'true' && needs.build.result == 'success' && needs.inference_smoke_tests.result == 'success' && needs.build_swift_sdk_artifact.result == 'success' && needs.build_linux_arm64.result == 'success' && (needs.build_linux_aarch64_cuda.result == 'success' || needs.build_linux_aarch64_cuda.result == 'skipped') && (needs.build_linux_cuda.result == 'success' || needs.build_linux_cuda.result == 'skipped') && (needs.build_linux_rocm.result == 'success' || needs.build_linux_rocm.result == 'skipped') && (needs.build_linux_vulkan.result == 'success' || needs.build_linux_vulkan.result == 'skipped') && needs.build_windows_cpu.result == 'success' && (needs.build_windows_gpu.result == 'success' || needs.build_windows_gpu.result == 'skipped') }}
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
Expand Down
47 changes: 47 additions & 0 deletions crates/mesh-llm-host-runtime/src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3573,6 +3573,7 @@ async fn run_runtime_cli(
let cli_has_explicit_models = cli_has_explicit_models(&options);
let has_config_models = !config.models.is_empty();
let has_startup_models = cli_has_explicit_models || has_config_models;
maybe_prepare_native_runtime(&options, has_startup_models).await?;

// Acquire the per-instance runtime directory and flock. Plain --client still
// skips this, but capture observers register so detached runs can be found
Expand Down Expand Up @@ -3952,6 +3953,30 @@ fn cli_has_explicit_models(options: &RuntimeOptions) -> bool {
!options.model.is_empty() || !options.gguf.is_empty()
}

fn should_prepare_native_runtime(options: &RuntimeOptions, has_startup_models: bool) -> bool {
has_startup_models || !options.client
}

async fn maybe_prepare_native_runtime(
options: &RuntimeOptions,
has_startup_models: bool,
) -> Result<()> {
if !should_prepare_native_runtime(options, has_startup_models) {
return Ok(());
}
#[cfg(feature = "dynamic-native-runtime")]
if let Some(runtime) =
crate::system::native_runtime::ensure_native_runtime_installed_and_loaded().await?
{
tracing::info!(
native_runtime_id = %runtime.native_runtime_id,
libraries = ?runtime.libraries,
"Loaded MeshLLM native runtime"
);
}
Ok(())
}

fn build_startup_model_specs(
options: &RuntimeOptions,
config: &plugin::MeshConfig,
Expand Down Expand Up @@ -11118,6 +11143,28 @@ mod tests {
assert!(!swarm_capture_observer_requested(&options));
}

#[test]
fn client_without_local_models_skips_native_runtime_prepare() {
let options = make_runtime_cli(&["mesh-llm", "client", "--auto"]);

assert!(!should_prepare_native_runtime(&options, false));
}

#[test]
fn serving_runtime_prepares_native_runtime_without_startup_models() {
let options = make_runtime_cli(&["mesh-llm", "serve"]);

assert!(should_prepare_native_runtime(&options, false));
}

#[test]
fn client_with_startup_models_prepares_native_runtime() {
let options =
make_runtime_cli(&["mesh-llm", "client", "--model", "hf://org/model/model.gguf"]);

assert!(should_prepare_native_runtime(&options, true));
}

#[test]
#[serial]
fn swarm_capture_env_client_registers_runtime_owner() {
Expand Down
2 changes: 1 addition & 1 deletion crates/mesh-llm-host-runtime/src/sdk/native_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ pub use mesh_llm_native_runtime::{
InstalledNativeRuntime, NATIVE_RUNTIME_MANIFEST_FILE, NativeRuntimeArtifact,
NativeRuntimeCache, NativeRuntimeCacheRoot, NativeRuntimeFlavor, NativeRuntimeFlavorParseError,
NativeRuntimeLoadPlan, NativeRuntimeManifest, NativeRuntimePruneMode,
NativeRuntimeReleaseManifest, NativeRuntimeResolution, NativeRuntimeResolver,
NativeRuntimeReleaseManifest, NativeRuntimeResolution, NativeRuntimeResolver, NativeRuntimeSdk,
NativeRuntimeSource, RuntimeSelection, native_runtime_cache_root, select_native_runtime,
};
Loading
Loading