mirror of
https://github.com/mostlygeek/llama-swap.git
synced 2026-09-07 16:37:22 +02:00
Big refactor to split the build stages for the unified container to be built in parallel. - parallel building of binaries to speed up full container build (~6+hr to 1.5hr) - split cuda and vulkan pipelines to be independent (vulkan is much faster) - establish pattern for building building binaries for final image (easier to add new resources) - use llama-swap-build for build containers to avoid untagged clean up script Fixes: #1069
159 lines
6.0 KiB
YAML
159 lines
6.0 KiB
YAML
name: Build Unified Docker Image
|
|
|
|
on:
|
|
schedule:
|
|
- cron: "37 5 * * *"
|
|
|
|
workflow_dispatch:
|
|
inputs:
|
|
llama_cpp_ref:
|
|
description: "llama.cpp commit hash, tag, or branch"
|
|
required: false
|
|
default: "master"
|
|
whisper_ref:
|
|
description: "whisper.cpp commit hash, tag, or branch"
|
|
required: false
|
|
default: "master"
|
|
sd_ref:
|
|
description: "stable-diffusion.cpp commit hash, tag, or branch"
|
|
required: false
|
|
default: "master"
|
|
audio_ref:
|
|
description: "audio.cpp commit hash, tag, or branch"
|
|
required: false
|
|
default: "main"
|
|
ik_llama_ref:
|
|
description: "ik_llama.cpp commit hash, tag, or branch (CUDA only)"
|
|
required: false
|
|
default: "main"
|
|
llama_swap_version:
|
|
description: "llama-swap version (e.g. v198, latest, main)"
|
|
required: false
|
|
default: "main"
|
|
build_cuda:
|
|
description: "Build CUDA image"
|
|
type: boolean
|
|
required: false
|
|
default: true
|
|
build_vulkan:
|
|
description: "Build Vulkan image"
|
|
type: boolean
|
|
required: false
|
|
default: true
|
|
push_to_ghcr:
|
|
description: "Push the unified images to ghcr.io (per-project artifacts images are always pushed; they are how the build stages reach the assemble job)"
|
|
type: boolean
|
|
required: false
|
|
default: true
|
|
|
|
permissions:
|
|
contents: read
|
|
packages: write
|
|
|
|
# The build is one Dockerfile per piece: a builder base per backend, one per
|
|
# upstream project, and the runtime. Each compiles in its own job and publishes
|
|
# an image; a final job copies the /install trees into the unified image.
|
|
#
|
|
# Building everything in one job put five concurrent CUDA compiles on a
|
|
# four-core runner, which stopped fitting in the 6h job limit; a cancelled job
|
|
# also never reached --cache-to, so nothing was cached and every later run
|
|
# rebuilt from scratch. Images are addressed by content -- the base by its
|
|
# Dockerfile, a project by its upstream commit plus its own two files and the
|
|
# base tag -- so anything unchanged is skipped, and one project overrunning no
|
|
# longer discards the others.
|
|
#
|
|
# Each backend runs as its own call to unified-docker-backend.yml, so Vulkan
|
|
# publishes as soon as its own projects finish rather than waiting on the
|
|
# multi-hour CUDA compiles.
|
|
jobs:
|
|
setup:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
build_cuda: ${{ steps.plan.outputs.build_cuda }}
|
|
build_vulkan: ${{ steps.plan.outputs.build_vulkan }}
|
|
cuda_projects: ${{ steps.plan.outputs.cuda_projects }}
|
|
vulkan_projects: ${{ steps.plan.outputs.vulkan_projects }}
|
|
push_to_ghcr: ${{ steps.plan.outputs.push_to_ghcr }}
|
|
llama_hash: ${{ steps.refs.outputs.llama_hash }}
|
|
whisper_hash: ${{ steps.refs.outputs.whisper_hash }}
|
|
sd_hash: ${{ steps.refs.outputs.sd_hash }}
|
|
audio_hash: ${{ steps.refs.outputs.audio_hash }}
|
|
ik_llama_hash: ${{ steps.refs.outputs.ik_llama_hash }}
|
|
ls_hash: ${{ steps.refs.outputs.ls_hash }}
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 6.0.2
|
|
|
|
# Resolve every ref once, here. The build and assemble jobs are handed
|
|
# full commit hashes, so a branch that moves mid-run cannot leave two
|
|
# jobs building different revisions of the same project.
|
|
- name: Resolve upstream commits
|
|
id: refs
|
|
env:
|
|
LLAMA_REF: ${{ inputs.llama_cpp_ref || 'master' }}
|
|
WHISPER_REF: ${{ inputs.whisper_ref || 'master' }}
|
|
SD_REF: ${{ inputs.sd_ref || 'master' }}
|
|
AUDIO_REF: ${{ inputs.audio_ref || 'main' }}
|
|
IK_LLAMA_REF: ${{ inputs.ik_llama_ref || 'main' }}
|
|
LS_VERSION: ${{ inputs.llama_swap_version || 'main' }}
|
|
run: |
|
|
chmod +x docker/unified/build-image.sh
|
|
docker/unified/build-image.sh --cuda --resolve | tee -a "$GITHUB_OUTPUT"
|
|
|
|
- name: Plan backends
|
|
id: plan
|
|
run: |
|
|
# schedule uses defaults (build both, push); workflow_dispatch respects inputs
|
|
if [[ "${{ github.event_name }}" == "schedule" ]]; then
|
|
build_cuda=true; build_vulkan=true; push=true
|
|
else
|
|
build_cuda="${{ inputs.build_cuda }}"
|
|
build_vulkan="${{ inputs.build_vulkan }}"
|
|
push="${{ inputs.push_to_ghcr }}"
|
|
fi
|
|
|
|
{
|
|
echo "build_cuda=${build_cuda}"
|
|
echo "build_vulkan=${build_vulkan}"
|
|
echo "push_to_ghcr=${push}"
|
|
# ik_llama.cpp has no Vulkan build.
|
|
echo 'cuda_projects=["whisper","sd","audio","llama","ik-llama"]'
|
|
echo 'vulkan_projects=["whisper","sd","audio","llama"]'
|
|
} >> "$GITHUB_OUTPUT"
|
|
|
|
cuda:
|
|
needs: setup
|
|
if: ${{ needs.setup.outputs.build_cuda == 'true' }}
|
|
uses: ./.github/workflows/unified-docker-backend.yml
|
|
permissions:
|
|
contents: read
|
|
packages: write
|
|
with:
|
|
backend: cuda
|
|
projects: ${{ needs.setup.outputs.cuda_projects }}
|
|
push_to_ghcr: ${{ needs.setup.outputs.push_to_ghcr == 'true' }}
|
|
llama_hash: ${{ needs.setup.outputs.llama_hash }}
|
|
whisper_hash: ${{ needs.setup.outputs.whisper_hash }}
|
|
sd_hash: ${{ needs.setup.outputs.sd_hash }}
|
|
audio_hash: ${{ needs.setup.outputs.audio_hash }}
|
|
ik_llama_hash: ${{ needs.setup.outputs.ik_llama_hash }}
|
|
ls_hash: ${{ needs.setup.outputs.ls_hash }}
|
|
|
|
vulkan:
|
|
needs: setup
|
|
if: ${{ needs.setup.outputs.build_vulkan == 'true' }}
|
|
uses: ./.github/workflows/unified-docker-backend.yml
|
|
permissions:
|
|
contents: read
|
|
packages: write
|
|
with:
|
|
backend: vulkan
|
|
projects: ${{ needs.setup.outputs.vulkan_projects }}
|
|
push_to_ghcr: ${{ needs.setup.outputs.push_to_ghcr == 'true' }}
|
|
llama_hash: ${{ needs.setup.outputs.llama_hash }}
|
|
whisper_hash: ${{ needs.setup.outputs.whisper_hash }}
|
|
sd_hash: ${{ needs.setup.outputs.sd_hash }}
|
|
audio_hash: ${{ needs.setup.outputs.audio_hash }}
|
|
ik_llama_hash: ${{ needs.setup.outputs.ik_llama_hash }}
|
|
ls_hash: ${{ needs.setup.outputs.ls_hash }}
|