Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
c7f6990
backend(audio-cpp): add the native build scaffold
mudler Jul 25, 2026
6ecde95
backend(audio-cpp): keep the build-tree rpath at $ORIGIN
mudler Jul 25, 2026
6c7e9ac
backend(audio-cpp): parse namespaced model options
mudler Jul 25, 2026
b2bca7a
backend(audio-cpp): reject out-of-range numeric model options
mudler Jul 25, 2026
56268eb
backend(audio-cpp): route LocalAI RPCs onto audio.cpp tasks
mudler Jul 25, 2026
5e05ba2
backend(audio-cpp): use upstream's 'spk' task name and pin the prefer…
mudler Jul 25, 2026
24ceb75
backend(audio-cpp): convert sample, time and PCM units
mudler Jul 25, 2026
7e666b8
backend(audio-cpp): harden seconds_to_samples against NaN and overflow
mudler Jul 25, 2026
a2a7115
backend(audio-cpp): map NaN PCM samples to silence explicitly
mudler Jul 26, 2026
8e3715c
backend(audio-cpp): assemble transcripts from runtime spans
mudler Jul 26, 2026
7cd8aa3
backend(audio-cpp): keep a nested speaker turn's own label
mudler Jul 26, 2026
9d36fcd
backend(audio-cpp): serialize runs with a wedge-aware guard
mudler Jul 26, 2026
87387d9
backend(audio-cpp): serialize inference through an InferenceLane
mudler Jul 26, 2026
7236858
backend(audio-cpp): make the B10 test able to fail, and document Lane…
mudler Jul 26, 2026
7f06179
backend(audio-cpp): gate model loading on the audio.cpp family
mudler Jul 26, 2026
9b394c4
backend(audio-cpp): load models and cache sessions per task
mudler Jul 26, 2026
a9a5970
backend(audio-cpp): stop aborting the process on SIGTERM
mudler Jul 26, 2026
fac26a2
backend(audio-cpp): correct the status, lifetime and state contracts …
mudler Jul 26, 2026
f08d5f8
backend(audio-cpp): serve the VAD and Diarize RPCs
mudler Jul 26, 2026
676e7bb
backend(audio-cpp): enforce ModelIdentity on VAD and Diarize
mudler Jul 26, 2026
51dec81
backend(audio-cpp): make the lane and identity guards structural
mudler Jul 26, 2026
6ee95ab
backend(audio-cpp): serve the AudioTranscription RPC
mudler Jul 26, 2026
f187bbf
backend(audio-cpp): stop linking sentencepiece's vendored protobuf
mudler Jul 26, 2026
bc6fd03
backend(audio-cpp): fix the segment text a transcription response is …
mudler Jul 26, 2026
5f010ac
backend(audio-cpp): serve the AudioTransform RPC
mudler Jul 26, 2026
2b1d3c9
backend(audio-cpp): refuse an impossible stem early, and stop blaming…
mudler Jul 26, 2026
81dba14
feat(audio-transform): stop folding every upload to 16 kHz mono, and …
mudler Jul 26, 2026
b93e7bd
fix(audio-transform): reject extensible WAV from the passthrough, esc…
mudler Jul 26, 2026
72f5154
backend(audio-cpp): serve the TTS and SoundGeneration RPCs
mudler Jul 26, 2026
b9a4c53
backend(audio-cpp): stop emitting an empty style language, and name t…
mudler Jul 26, 2026
41b4e72
backend(audio-cpp): serve the TTSStream and AudioTranscriptionStream …
mudler Jul 26, 2026
f9eead3
backend(audio-cpp): keep streaming deltas on UTF-8 boundaries, refuse…
mudler Jul 26, 2026
f00dcad
backend(audio-cpp): stop a repeated lead byte from orphaning the next…
mudler Jul 26, 2026
9e649bc
backend(audio-cpp): read only an exact repeat as a repeat, not any pr…
mudler Jul 26, 2026
8778600
backend(audio-cpp): serve the AudioTranscriptionLive RPC
mudler Jul 27, 2026
2f6e048
backend(audio-cpp): bound the lane a live stream can hold
mudler Jul 27, 2026
7a244b5
backend(audio-cpp): refuse the unsupported RPCs with a reason
mudler Jul 27, 2026
1819737
backend(audio-cpp): correct the vevo2 clause, and assert the absences
mudler Jul 27, 2026
9a2f2b9
backend(audio-cpp): make the missing-switch-case diagnostic fatal
mudler Jul 27, 2026
40b677f
backend(audio-cpp): package the backend image
mudler Jul 27, 2026
3b2ef6e
backend(audio-cpp): exempt the driver libraries from the packaging gate
mudler Jul 27, 2026
ea93697
backend(audio-cpp): register the backend with CI and the gallery
mudler Jul 27, 2026
62e1b48
backend(audio-cpp): pin the CUDA architectures, drop the vulkan variant
mudler Jul 27, 2026
bb09392
backend(audio-cpp): build for Darwin Metal
mudler Jul 27, 2026
e5236ed
backend(audio-cpp): make the Darwin fallbacks loud and the rpath walk…
mudler Jul 27, 2026
842443c
backend(audio-cpp): make bundled: reachable from a model YAML
mudler Jul 27, 2026
d8b6150
backend(audio-cpp): advertise the backend and document its options
mudler Jul 27, 2026
c98b821
backend(audio-cpp): test resolve_model_path, and correct the family n…
mudler Jul 27, 2026
168255c
gallery: add audio.cpp models covering every served RPC
mudler Jul 27, 2026
2d21b3e
gallery: correct the audio.cpp entries' licenses
mudler Jul 27, 2026
a84b3c4
fix(audio-transform): bound sample_rate, keep same-named uploads apart
mudler Jul 27, 2026
b7ada17
fix(audio-cpp): refuse a task pin the RPC cannot serve, and stop empt…
mudler Jul 27, 2026
8a6a693
build(audio-cpp): exclude the upstream checkout from the C++ gate, ha…
mudler Jul 27, 2026
3933e38
style(audio-cpp): drop em dashes from the audio-cpp capability entry
mudler Jul 27, 2026
7d61faf
fix(config): key the voice-cloning model rule on the resolved backend
mudler Jul 27, 2026
35dbaf0
gallery(audio-cpp): declare audio_transform on the chatterbox entry
mudler Jul 27, 2026
3bf2b4e
gallery(audio-cpp): add voice-design and singing-voice-conversion ent…
mudler Jul 27, 2026
cdf2ccb
backend(audio-cpp): carry transform text through params, add the s2s …
mudler Jul 27, 2026
2a0b159
docs(audio-cpp): document params[text] and the pinned transform tasks
mudler Jul 27, 2026
cc5ae3f
fix(utils): annotate the two G304 sites this branch introduced
mudler Jul 27, 2026
9c758dc
Merge branch 'master' into feat/audio-cpp-native-backend
mudler Jul 27, 2026
b7ecc1b
fix(audio-cpp): build arm64 with gcc-14 for the armv9.2 SME variants
mudler Jul 27, 2026
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
10 changes: 10 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ backend/cpp/privacy-filter/build
backend/cpp/privacy-filter/grpc-server
backend/cpp/privacy-filter/package

# audio-cpp: same in-place pattern. The Makefile clones audio.cpp at the pinned
# AUDIO_CPP_VERSION and the `audio.cpp:` target is the directory itself, so a
# stale host checkout COPY'd in makes the build compile against whatever commit
# the host had. build/ is worse than stale: its CMakeCache.txt records the host
# source, prefix and compiler paths, and cmake refuses to reconfigure from it.
backend/cpp/audio-cpp/audio.cpp
backend/cpp/audio-cpp/build
backend/cpp/audio-cpp/grpc-server
backend/cpp/audio-cpp/package

# Rust backend build output (sources are tracked; target/ is generated)
backend/rust/*/target

Expand Down
103 changes: 103 additions & 0 deletions .github/backend-matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3076,6 +3076,97 @@ include:
dockerfile: "./backend/Dockerfile.privacy-filter"
context: "./"
ubuntu-version: '2404'
# audio-cpp: 0xShug0/audio.cpp, a multi-family ggml audio engine (TTS, ASR,
# VAD, diarization, source separation, music generation).
#
# These entries deliberately carry NO builder-base-image, unlike the
# privacy-filter and llama-cpp blocks above. The prebuilt
# quay.io/go-skynet/ci-cache:base-grpc-* images ship a from-source gRPC whose
# protobuf is v26, and protobuf has depended on abseil since v22. audio.cpp
# links sentencepiece with SPM_PROTOBUF_PROVIDER=package (needed to stop
# sentencepiece's vendored protobuf 3.14 from colliding with the 3.21 the
# generated backend.pb.cc is built against, which broke every nested-message
# parse), so sentencepiece then sees real abseil's
# `absl::lts_20240116::internal` alongside its own vendored plain
# `absl::internal` and every `absl::internal::` reference becomes ambiguous.
# Verified, not theorised: building against base-grpc-amd64 fails at
# sentencepiece-static.dir/error.cc.o with "reference to 'internal' is
# ambiguous". Dockerfile.audio-cpp therefore installs Ubuntu Noble's apt
# gRPC/protobuf 3.21.12 itself and has a single `builder` stage, so the
# BUILDER_BASE_IMAGE / BUILDER_TARGET / SKIP_DRIVERS build-args are never
# consumed. Same reason CUDA needs its toolkit in base-image rather than in a
# builder image: this is the ds4 shape, not the llama-cpp one.
#
# No ROCm entry: upstream has no HIP configuration. No CUDA arm64 or L4T
# entry: upstream documents and validates CUDA on x86 only. Darwin/Metal is in
# the includeDarwin matrix below, built by scripts/build/audio-cpp-darwin.sh.
#
# No vulkan entry either, though Dockerfile.audio-cpp and the backend Makefile
# both handle BUILD_TYPE=vulkan for local builds. Every other vulkan backend
# gets its Mesa ICD drivers from .docker/install-base-deps.sh, which installs
# mesa-vulkan-drivers so package-gpu-libs.sh can bundle them; this Dockerfile
# calls neither, so the image would ship a Vulkan loader that finds no GPU. No
# CI job runs a vulkan image against real hardware, so it would pass green and
# fail in users' hands. The entry comes back once the ICD question is settled.
- build-type: ''
cuda-major-version: ""
cuda-minor-version: ""
platforms: 'linux/amd64'
platform-tag: 'amd64'
tag-latest: 'auto'
tag-suffix: '-cpu-audio-cpp'
runs-on: 'ubuntu-latest'
base-image: "ubuntu:24.04"
skip-drivers: 'true'
backend: "audio-cpp"
dockerfile: "./backend/Dockerfile.audio-cpp"
context: "./"
ubuntu-version: '2404'
- build-type: ''
cuda-major-version: ""
cuda-minor-version: ""
platforms: 'linux/arm64'
platform-tag: 'arm64'
tag-latest: 'auto'
tag-suffix: '-cpu-audio-cpp'
runs-on: 'ubuntu-24.04-arm'
base-image: "ubuntu:24.04"
skip-drivers: 'true'
backend: "audio-cpp"
dockerfile: "./backend/Dockerfile.audio-cpp"
context: "./"
ubuntu-version: '2404'
# cuda-major-version is forwarded into the build (Dockerfile.audio-cpp -> the
# backend Makefile) and picks the CMAKE_CUDA_ARCHITECTURES list, which upstream
# otherwise sets to `native` and no CI runner can enumerate. cuda-minor-version
# and the base-image tag encode the same toolkit and must move together;
# nothing checks that for you.
- build-type: 'cublas'
cuda-major-version: "12"
cuda-minor-version: "8"
platforms: 'linux/amd64'
tag-latest: 'auto'
tag-suffix: '-gpu-nvidia-cuda-12-audio-cpp'
runs-on: 'ubuntu-latest'
base-image: "nvidia/cuda:12.8.1-devel-ubuntu24.04"
skip-drivers: 'true'
backend: "audio-cpp"
dockerfile: "./backend/Dockerfile.audio-cpp"
context: "./"
ubuntu-version: '2404'
- build-type: 'cublas'
cuda-major-version: "13"
cuda-minor-version: "0"
platforms: 'linux/amd64'
tag-latest: 'auto'
tag-suffix: '-gpu-nvidia-cuda-13-audio-cpp'
runs-on: 'ubuntu-latest'
base-image: "nvidia/cuda:13.0.0-devel-ubuntu24.04"
skip-drivers: 'true'
backend: "audio-cpp"
dockerfile: "./backend/Dockerfile.audio-cpp"
context: "./"
ubuntu-version: '2404'
- build-type: ''
cuda-major-version: ""
cuda-minor-version: ""
Expand Down Expand Up @@ -6030,6 +6121,18 @@ includeDarwin:
- backend: "privacy-filter"
tag-suffix: "-metal-darwin-arm64-privacy-filter"
lang: "go"
# audio-cpp is the same shape: a C++/ggml backend built by a bespoke darwin
# script (make backends/audio-cpp-darwin), which reuses the backend's own
# package.sh so the Darwin package keeps the root-level layout the Linux image
# has (grpc-server, run.sh and assets/ in one directory, dylibs in lib/).
# No build-type: the backend Makefile turns ENGINE_ENABLE_METAL on from
# uname -s. lang=go drives runner/toolchain selection only - there is no
# backend/go/audio-cpp, which is why backend_build_darwin.yml and
# DARWIN_BESPOKE_BUILDERS in scripts/lib/backend-filter.mjs both route this
# backend away from the generic Go path.
- backend: "audio-cpp"
tag-suffix: "-metal-darwin-arm64-audio-cpp"
lang: "go"
# LocalVQE has no Metal path; on Apple Silicon it builds CPU-only (GGML_METAL
# OFF) but is still a native arm64 image. Uses the darwin/metal build profile.
- backend: "localvqe"
Expand Down
13 changes: 12 additions & 1 deletion .github/workflows/backend_build_darwin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,19 @@ jobs:
make protogen-go
make backends/privacy-filter-darwin

# audio-cpp is a C++/ggml backend like ds4 and privacy-filter - a single
# grpc-server with otool dylib bundling, plus bundled VAD assets - so it
# gets its own bespoke darwin script rather than the generic
# build-darwin-go-backend path, which would look for a backend/go/audio-cpp
# that does not exist. Keep this set in sync with DARWIN_BESPOKE_BUILDERS
# in scripts/lib/backend-filter.mjs.
- name: Build audio-cpp backend (Darwin Metal)
if: inputs.backend == 'audio-cpp'
run: |
make backends/audio-cpp-darwin

- name: Build ${{ inputs.backend }}-darwin
if: inputs.backend != 'llama-cpp' && inputs.backend != 'ds4' && inputs.backend != 'privacy-filter'
if: inputs.backend != 'llama-cpp' && inputs.backend != 'ds4' && inputs.backend != 'privacy-filter' && inputs.backend != 'audio-cpp'
run: |
make protogen-go
BACKEND=${{ inputs.backend }} BUILD_TYPE=${{ inputs.build-type }} USE_PIP=${{ inputs.use-pip }} make build-darwin-${{ inputs.lang }}-backend
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/bump_deps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ jobs:
variable: "DS4_VERSION"
branch: "main"
file: "backend/cpp/ds4/Makefile"
- repository: "0xShug0/audio.cpp"
variable: "AUDIO_CPP_VERSION"
branch: "main"
file: "backend/cpp/audio-cpp/Makefile"
- repository: "meituan-longcat/LongCat-Video"
variable: "LONGCAT_VIDEO_VERSION"
branch: "main"
Expand Down
14 changes: 12 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Disable parallel execution for backend builds
.NOTPARALLEL: backends/diffusers backends/llama-cpp backends/turboquant backends/bonsai backends/outetts backends/piper backends/stablediffusion-ggml backends/whisper backends/crispasr backends/parakeet-cpp backends/moss-transcribe-cpp backends/faster-whisper backends/silero-vad backends/local-store backends/cloud-proxy backends/huggingface backends/rfdetr backends/rfdetr-cpp backends/insightface backends/speaker-recognition backends/kitten-tts backends/kokoro backends/chatterbox backends/llama-cpp-darwin backends/neutts build-darwin-python-backend build-darwin-go-backend backends/mlx backends/diffuser-darwin backends/mlx-vlm backends/mlx-audio backends/mlx-distributed backends/stablediffusion-ggml-darwin backends/vllm backends/vllm-omni backends/longcat-video backends/sglang backends/moonshine backends/pocket-tts backends/qwen-tts backends/faster-qwen3-tts backends/qwen-asr backends/nemo backends/voxcpm backends/whisperx backends/ace-step backends/acestep-cpp backends/fish-speech backends/voxtral backends/opus backends/trl backends/llama-cpp-quantization backends/kokoros backends/sam3-cpp backends/qwen3-tts-cpp backends/moss-tts-cpp backends/magpie-tts-cpp backends/vllm-cpp backends/omnivoice-cpp backends/vibevoice-cpp backends/localvqe backends/tinygrad backends/sherpa-onnx backends/ds4 backends/ds4-darwin backends/liquid-audio backends/supertonic backends/depth-anything-cpp backends/privacy-filter backends/privacy-filter-darwin
.NOTPARALLEL: backends/diffusers backends/llama-cpp backends/turboquant backends/bonsai backends/outetts backends/piper backends/stablediffusion-ggml backends/whisper backends/crispasr backends/parakeet-cpp backends/moss-transcribe-cpp backends/faster-whisper backends/silero-vad backends/local-store backends/cloud-proxy backends/huggingface backends/rfdetr backends/rfdetr-cpp backends/insightface backends/speaker-recognition backends/kitten-tts backends/kokoro backends/chatterbox backends/llama-cpp-darwin backends/neutts build-darwin-python-backend build-darwin-go-backend backends/mlx backends/diffuser-darwin backends/mlx-vlm backends/mlx-audio backends/mlx-distributed backends/stablediffusion-ggml-darwin backends/vllm backends/vllm-omni backends/longcat-video backends/sglang backends/moonshine backends/pocket-tts backends/qwen-tts backends/faster-qwen3-tts backends/qwen-asr backends/nemo backends/voxcpm backends/whisperx backends/ace-step backends/acestep-cpp backends/fish-speech backends/voxtral backends/opus backends/trl backends/llama-cpp-quantization backends/kokoros backends/sam3-cpp backends/qwen3-tts-cpp backends/moss-tts-cpp backends/magpie-tts-cpp backends/vllm-cpp backends/omnivoice-cpp backends/vibevoice-cpp backends/localvqe backends/tinygrad backends/sherpa-onnx backends/ds4 backends/ds4-darwin backends/liquid-audio backends/supertonic backends/depth-anything-cpp backends/privacy-filter backends/privacy-filter-darwin backends/audio-cpp backends/audio-cpp-darwin

GOCMD=go
GOTEST=$(GOCMD) test
Expand Down Expand Up @@ -1188,6 +1188,10 @@ backends/privacy-filter-darwin: build
bash ./scripts/build/privacy-filter-darwin.sh
./local-ai backends install "ocifile://$(abspath ./backend-images/privacy-filter.tar)"

backends/audio-cpp-darwin: build
bash ./scripts/build/audio-cpp-darwin.sh
./local-ai backends install "ocifile://$(abspath ./backend-images/audio-cpp.tar)"

build-darwin-python-backend: build
bash ./scripts/build/python-darwin.sh

Expand Down Expand Up @@ -1241,6 +1245,11 @@ BACKEND_DS4 = ds4|ds4|.|false|false
# openai-privacy-filter PII/NER token classifier) — the TokenClassify RPC for
# the PII redactor tier, on stock ggml with no llama.cpp carry-patches.
BACKEND_PRIVACY_FILTER = privacy-filter|privacy-filter|.|false|false
# audio-cpp wraps 0xShug0/audio.cpp, a multi-family ggml audio inference engine
# (TTS, ASR, VAD, diarization, source separation, music generation). Builds
# against apt gRPC/protobuf rather than a prebuilt base-grpc image; the reason
# is on the audio-cpp block in .github/backend-matrix.yml.
BACKEND_AUDIO_CPP = audio-cpp|audio-cpp|.|false|false

# Golang backends
BACKEND_PIPER = piper|golang|.|false|true
Expand Down Expand Up @@ -1342,6 +1351,7 @@ $(eval $(call generate-docker-build-target,$(BACKEND_TURBOQUANT)))
$(eval $(call generate-docker-build-target,$(BACKEND_BONSAI)))
$(eval $(call generate-docker-build-target,$(BACKEND_DS4)))
$(eval $(call generate-docker-build-target,$(BACKEND_PRIVACY_FILTER)))
$(eval $(call generate-docker-build-target,$(BACKEND_AUDIO_CPP)))
$(eval $(call generate-docker-build-target,$(BACKEND_PIPER)))
$(eval $(call generate-docker-build-target,$(BACKEND_LOCAL_STORE)))
$(eval $(call generate-docker-build-target,$(BACKEND_CLOUD_PROXY)))
Expand Down Expand Up @@ -1408,7 +1418,7 @@ $(eval $(call generate-docker-build-target,$(BACKEND_SUPERTONIC)))
docker-save-%: backend-images
docker save local-ai-backend:$* -o backend-images/$*.tar

docker-build-backends: docker-build-llama-cpp docker-build-ik-llama-cpp docker-build-turboquant docker-build-bonsai docker-build-ds4 docker-build-rerankers docker-build-vllm docker-build-vllm-omni docker-build-longcat-video docker-build-sglang docker-build-transformers docker-build-outetts docker-build-diffusers docker-build-kokoro docker-build-faster-whisper docker-build-crispasr docker-build-coqui docker-build-chatterbox docker-build-vibevoice docker-build-liquid-audio docker-build-moonshine docker-build-pocket-tts docker-build-qwen-tts docker-build-fish-speech docker-build-faster-qwen3-tts docker-build-qwen-asr docker-build-nemo docker-build-voxcpm docker-build-whisperx docker-build-ace-step docker-build-acestep-cpp docker-build-voxtral docker-build-mlx-distributed docker-build-trl docker-build-llama-cpp-quantization docker-build-tinygrad docker-build-kokoros docker-build-sam3-cpp docker-build-rfdetr-cpp docker-build-qwen3-tts-cpp docker-build-moss-tts-cpp docker-build-magpie-tts-cpp docker-build-vllm-cpp docker-build-omnivoice-cpp docker-build-vibevoice-cpp docker-build-localvqe docker-build-insightface docker-build-speaker-recognition docker-build-sherpa-onnx docker-build-cloud-proxy docker-build-supertonic docker-build-depth-anything-cpp docker-build-moss-transcribe-cpp docker-build-privacy-filter
docker-build-backends: docker-build-llama-cpp docker-build-ik-llama-cpp docker-build-turboquant docker-build-bonsai docker-build-ds4 docker-build-rerankers docker-build-vllm docker-build-vllm-omni docker-build-longcat-video docker-build-sglang docker-build-transformers docker-build-outetts docker-build-diffusers docker-build-kokoro docker-build-faster-whisper docker-build-crispasr docker-build-coqui docker-build-chatterbox docker-build-vibevoice docker-build-liquid-audio docker-build-moonshine docker-build-pocket-tts docker-build-qwen-tts docker-build-fish-speech docker-build-faster-qwen3-tts docker-build-qwen-asr docker-build-nemo docker-build-voxcpm docker-build-whisperx docker-build-ace-step docker-build-acestep-cpp docker-build-voxtral docker-build-mlx-distributed docker-build-trl docker-build-llama-cpp-quantization docker-build-tinygrad docker-build-kokoros docker-build-sam3-cpp docker-build-rfdetr-cpp docker-build-qwen3-tts-cpp docker-build-moss-tts-cpp docker-build-magpie-tts-cpp docker-build-vllm-cpp docker-build-omnivoice-cpp docker-build-vibevoice-cpp docker-build-localvqe docker-build-insightface docker-build-speaker-recognition docker-build-sherpa-onnx docker-build-cloud-proxy docker-build-supertonic docker-build-depth-anything-cpp docker-build-moss-transcribe-cpp docker-build-privacy-filter docker-build-audio-cpp

########################################################
### Mock Backend for E2E Tests
Expand Down
Loading
Loading