2026-01-06 14:26:42 +00:00
# Disable parallel execution for backend builds
2026-03-22 00:56:34 +01:00
.NOTPARALLEL : backends /diffusers backends /llama -cpp backends /outetts backends /piper backends /stablediffusion -ggml backends /whisper backends /faster -whisper backends /silero -vad backends /local -store backends /huggingface backends /rfdetr 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 /moonshine backends /pocket -tts backends /qwen -tts backends /faster -qwen 3-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
2026-01-06 14:26:42 +00:00
2023-04-15 16:39:07 -07:00
GOCMD = go
GOTEST = $( GOCMD) test
GOVET = $( GOCMD) vet
2023-04-19 18:43:10 +02:00
BINARY_NAME = local-ai
2025-08-26 14:22:04 +02:00
LAUNCHER_BINARY_NAME = local-ai-launcher
2023-05-04 12:26:59 +02:00
2026-01-13 23:35:19 +01:00
UBUNTU_VERSION ?= 2404
2026-01-06 14:26:42 +00:00
UBUNTU_CODENAME ?= noble
2025-12-02 14:24:35 +01:00
2025-07-22 16:31:04 +02:00
GORELEASER ?=
2024-11-20 14:48:40 +01:00
2023-06-05 14:26:20 +02:00
export BUILD_TYPE ?=
2026-01-30 12:58:44 +01:00
export CUDA_MAJOR_VERSION ?= 13
export CUDA_MINOR_VERSION ?= 0
2025-07-20 22:52:45 +02:00
2023-05-16 19:32:53 +02:00
GO_TAGS ?=
2024-05-10 16:01:55 +02:00
BUILD_ID ?=
2024-11-18 13:59:06 +01:00
NATIVE ?= false
2023-06-26 15:12:43 +02:00
2023-10-19 13:50:40 +02:00
TEST_DIR = /tmp/test
2024-03-01 10:19:53 -05:00
TEST_FLAKES ?= 5
2023-10-19 13:50:40 +02:00
RANDOM := $( shell bash -c 'echo $$RANDOM' )
2023-07-02 11:14:09 +02:00
VERSION ?= $( shell git describe --always --tags || echo "dev" )
2023-06-26 15:12:43 +02:00
# go tool nm ./local-ai | grep Commit
2024-07-22 15:39:57 +02:00
LD_FLAGS ?= -s -w
2024-07-08 22:04:06 +02:00
o v e r r i d e LD_FLAGS += -X " github.com/mudler/LocalAI/internal.Version= $( VERSION) "
o v e r r i d e LD_FLAGS += -X " github.com/mudler/LocalAI/internal.Commit= $( shell git rev-parse HEAD) "
2023-06-26 15:12:43 +02:00
2023-05-16 19:32:53 +02:00
OPTIONAL_TARGETS ?=
2023-05-03 11:45:22 +02:00
2024-06-26 14:58:38 +02:00
export OS := $( shell uname -s)
2023-05-23 17:12:48 +02:00
ARCH := $( shell uname -m)
2023-04-15 16:39:07 -07:00
GREEN := $( shell tput -Txterm setaf 2)
YELLOW := $( shell tput -Txterm setaf 3)
WHITE := $( shell tput -Txterm setaf 7)
CYAN := $( shell tput -Txterm setaf 6)
RESET := $( shell tput -Txterm sgr0)
2023-10-19 13:50:40 +02:00
# Default Docker bridge IP
E2E_BRIDGE_IP ?= 172.17.0.1
2023-07-15 01:19:43 +02:00
i f n d e f U N A M E _ S
UNAME_S := $( shell uname -s)
e n d i f
2024-11-20 14:48:40 +01:00
2023-11-30 13:50:50 -05:00
i f e q ( $( OS ) , D a r w i n )
i f e q ( $( OSX_SIGNING_IDENTITY ) , )
OSX_SIGNING_IDENTITY := $( shell security find-identity -v -p codesigning | grep '"' | head -n 1 | sed -E 's/.*"(.*)"/\1/' )
endif
2023-05-24 16:42:24 +02:00
e n d i f
2025-07-22 16:31:04 +02:00
# check if goreleaser exists
i f e q ( , $( shell which goreleaser ) )
GORELEASER = curl -sfL https://goreleaser.com/static/run | bash -s --
e l s e
GORELEASER = $( shell which goreleaser)
e n d i f
2024-02-08 20:12:51 +01:00
2024-02-27 15:04:19 +01:00
TEST_PATHS ?= ./api/... ./pkg/... ./core/...
2023-10-21 11:34:59 +02:00
2024-01-19 15:38:43 +01:00
2025-07-20 22:52:45 +02:00
.PHONY : all test build vendor
2023-04-15 16:39:07 -07:00
all : help
2023-05-03 11:45:22 +02:00
## GENERIC
rebuild : ## Rebuilds the project
2023-07-05 18:24:55 +02:00
$( GOCMD) clean -cache
2023-04-29 20:38:37 +02:00
$( MAKE) build
2023-04-15 16:39:07 -07:00
clean : ## Remove build related file
2023-07-05 18:24:55 +02:00
$( GOCMD) clean -cache
2023-07-25 17:02:46 -04:00
rm -f prepare
2023-04-19 17:10:29 +02:00
rm -rf $( BINARY_NAME)
2023-05-23 17:12:48 +02:00
rm -rf release/
2024-04-13 02:37:32 -05:00
$( MAKE) protogen-clean
rmdir pkg/grpc/proto || true
2023-04-15 16:39:07 -07:00
2024-03-18 14:19:43 -04:00
clean-tests :
rm -rf test-models
rm -rf test-dir
2024-09-24 03:32:48 -04:00
2025-05-04 16:42:42 +02:00
## Install Go tools
install-go-tools :
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@1958fcbe2ca8bd93af633f11e97d44e567e945af
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.34.2
2026-03-05 21:47:12 +01:00
## React UI:
react-ui :
i f n e q ( $( wildcard core /http /react -ui /dist ) , )
@ e c h o "react-ui dist already exists, skipping build"
e l s e
c d c o r e / h t t p / r e a c t - u i & & n p m i n s t a l l & & n p m r u n b u i l d
e n d i f
react-ui-docker :
docker run --entrypoint /bin/bash -v $( CURDIR) :/app:z oven/bun:1 \
-c "cd /app/core/http/react-ui && bun install && bun run build"
core/http/react-ui/dist : react -ui
2023-05-03 11:45:22 +02:00
## Build:
2026-03-13 20:37:15 +00:00
2026-03-22 00:57:15 +01:00
build : protogen -go generate install -go -tools core /http /react -ui /dist ## Build the project
2023-05-03 11:45:22 +02:00
$( info ${ GREEN } I local-ai build info:${ RESET } )
$( info ${ GREEN } I BUILD_TYPE: ${ YELLOW } $( BUILD_TYPE) ${ RESET } )
2023-05-16 19:32:53 +02:00
$( info ${ GREEN } I GO_TAGS: ${ YELLOW } $( GO_TAGS) ${ RESET } )
2023-06-26 15:12:43 +02:00
$( info ${ GREEN } I LD_FLAGS: ${ YELLOW } $( LD_FLAGS) ${ RESET } )
2024-07-22 15:39:57 +02:00
$( info ${ GREEN } I UPX: ${ YELLOW } $( UPX) ${ RESET } )
2025-05-04 16:42:42 +02:00
rm -rf $( BINARY_NAME) || true
2025-08-26 19:07:10 +02:00
CGO_LDFLAGS = " $( CGO_LDFLAGS) " $( GOCMD) build -ldflags " $( LD_FLAGS) " -tags " $( GO_TAGS) " -o $( BINARY_NAME) ./cmd/local-ai
2025-08-26 14:22:04 +02:00
build-launcher : ## Build the launcher application
$( info ${ GREEN } I local-ai launcher build info:${ RESET } )
$( info ${ GREEN } I BUILD_TYPE: ${ YELLOW } $( BUILD_TYPE) ${ RESET } )
$( info ${ GREEN } I GO_TAGS: ${ YELLOW } $( GO_TAGS) ${ RESET } )
$( info ${ GREEN } I LD_FLAGS: ${ YELLOW } $( LD_FLAGS) ${ RESET } )
rm -rf $( LAUNCHER_BINARY_NAME) || true
2025-08-26 19:07:10 +02:00
CGO_LDFLAGS = " $( CGO_LDFLAGS) " $( GOCMD) build -ldflags " $( LD_FLAGS) " -tags " $( GO_TAGS) " -o $( LAUNCHER_BINARY_NAME) ./cmd/launcher
2025-08-26 14:22:04 +02:00
build-all : build build -launcher ## Build both server and launcher
2023-05-03 11:45:22 +02:00
2025-11-08 02:53:44 +06:00
build-dev : ## Run LocalAI in dev mode with live reload
@command -v air >/dev/null 2>& 1 || go install github.com/air-verse/air@latest
air -c .air.toml
2025-07-22 16:31:04 +02:00
dev-dist :
$( GORELEASER) build --snapshot --clean
2024-06-14 08:51:25 +02:00
2024-05-14 10:40:18 -07:00
dist :
2025-07-22 16:31:04 +02:00
$( GORELEASER) build --clean
2023-05-23 17:12:48 +02:00
2023-11-23 09:22:54 -05:00
osx-signed : build
codesign --deep --force --sign " $( OSX_SIGNING_IDENTITY) " --entitlements "./Entitlements.plist" " ./ $( BINARY_NAME) "
2023-05-03 11:45:22 +02:00
## Run
2025-07-20 22:52:45 +02:00
run : ## run local-ai
2023-07-15 01:19:43 +02:00
CGO_LDFLAGS = " $( CGO_LDFLAGS) " $( GOCMD) run ./
2023-04-15 16:39:07 -07:00
2024-03-18 14:19:43 -04:00
test-models/testmodel.ggml :
2025-09-13 23:11:54 +02:00
mkdir -p test-models
mkdir -p test-dir
2025-05-26 17:19:46 +02:00
wget -q https://huggingface.co/mradermacher/gpt2-alpaca-gpt4-GGUF/resolve/main/gpt2-alpaca-gpt4.Q4_K_M.gguf -O test-models/testmodel.ggml
feat(conda): conda environments (#1144)
* feat(autogptq): add a separate conda environment for autogptq (#1137)
**Description**
This PR related to #1117
**Notes for Reviewers**
Here we lock down the version of the dependencies. Make sure it can be
used all the time without failed if the version of dependencies were
upgraded.
I change the order of importing packages according to the pylint, and no
change the logic of code. It should be ok.
I will do more investigate on writing some test cases for every backend.
I can run the service in my environment, but there is not exist a way to
test it. So, I am not confident on it.
Add a README.md in the `grpc` root. This is the common commands for
creating `conda` environment. And it can be used to the reference file
for creating extral gRPC backend document.
Signed-off-by: GitHub <noreply@github.com>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* [Extra backend] Add seperate environment for ttsbark (#1141)
**Description**
This PR relates to #1117
**Notes for Reviewers**
Same to the latest PR:
* The code is also changed, but only the order of the import package
parts. And some code comments are also added.
* Add a configuration of the `conda` environment
* Add a simple test case for testing if the service can be startup in
current `conda` environment. It is succeed in VSCode, but the it is not
out of box on terminal. So, it is hard to say the test case really
useful.
**[Signed
commits](../CONTRIBUTING.md#signing-off-on-commits-developer-certificate-of-origin)**
- [x] Yes, I signed my commits.
<!--
Thank you for contributing to LocalAI!
Contributing Conventions
-------------------------
The draft above helps to give a quick overview of your PR.
Remember to remove this comment and to at least:
1. Include descriptive PR titles with [<component-name>] prepended. We
use [conventional
commits](https://www.conventionalcommits.org/en/v1.0.0/).
2. Build and test your changes before submitting a PR (`make build`).
3. Sign your commits
4. **Tag maintainer:** for a quicker response, tag the relevant
maintainer (see below).
5. **X/Twitter handle:** we announce bigger features on X/Twitter. If
your PR gets announced, and you'd like a mention, we'll gladly shout you
out!
By following the community's contribution conventions upfront, the
review process will
be accelerated and your PR merged more quickly.
If no one reviews your PR within a few days, please @-mention @mudler.
-->
Signed-off-by: GitHub <noreply@github.com>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* feat(conda): add make target and entrypoints for the dockerfile
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* feat(conda): Add seperate conda env for diffusers (#1145)
**Description**
This PR relates to #1117
**Notes for Reviewers**
* Add `conda` env `diffusers.yml`
* Add Makefile to create it automatically
* Add `run.sh` to support running as a extra backend
* Also adding it to the main Dockerfile
* Add make command in the root Makefile
* Testing the server, it can start up under the env
Signed-off-by: GitHub <noreply@github.com>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* feat(conda):Add seperate env for vllm (#1148)
**Description**
This PR is related to #1117
**Notes for Reviewers**
* The gRPC server can be started as normal
* The test case can be triggered in VSCode
* Same to other this kind of PRs, add `vllm.yml` Makefile and add
`run.sh` to the main Dockerfile, and command to the main Makefile
**[Signed
commits](../CONTRIBUTING.md#signing-off-on-commits-developer-certificate-of-origin)**
- [x] Yes, I signed my commits.
<!--
Thank you for contributing to LocalAI!
Contributing Conventions
-------------------------
The draft above helps to give a quick overview of your PR.
Remember to remove this comment and to at least:
1. Include descriptive PR titles with [<component-name>] prepended. We
use [conventional
commits](https://www.conventionalcommits.org/en/v1.0.0/).
2. Build and test your changes before submitting a PR (`make build`).
3. Sign your commits
4. **Tag maintainer:** for a quicker response, tag the relevant
maintainer (see below).
5. **X/Twitter handle:** we announce bigger features on X/Twitter. If
your PR gets announced, and you'd like a mention, we'll gladly shout you
out!
By following the community's contribution conventions upfront, the
review process will
be accelerated and your PR merged more quickly.
If no one reviews your PR within a few days, please @-mention @mudler.
-->
Signed-off-by: GitHub <noreply@github.com>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* feat(conda):Add seperate env for huggingface (#1146)
**Description**
This PR is related to #1117
**Notes for Reviewers**
* Add conda env `huggingface.yml`
* Change the import order, and also remove the no-used packages
* Add `run.sh` and `make command` to the main Dockerfile and Makefile
* Add test cases for it. It can be triggered and succeed under VSCode
Python extension but it is hang by using `python -m unites
test_huggingface.py` in the terminal
```
Running tests (unittest): /workspaces/LocalAI/extra/grpc/huggingface
Running tests: /workspaces/LocalAI/extra/grpc/huggingface/test_huggingface.py::TestBackendServicer::test_embedding
/workspaces/LocalAI/extra/grpc/huggingface/test_huggingface.py::TestBackendServicer::test_load_model
/workspaces/LocalAI/extra/grpc/huggingface/test_huggingface.py::TestBackendServicer::test_server_startup
./test_huggingface.py::TestBackendServicer::test_embedding Passed
./test_huggingface.py::TestBackendServicer::test_load_model Passed
./test_huggingface.py::TestBackendServicer::test_server_startup Passed
Total number of tests expected to run: 3
Total number of tests run: 3
Total number of tests passed: 3
Total number of tests failed: 0
Total number of tests failed with errors: 0
Total number of tests skipped: 0
Finished running tests!
```
**[Signed
commits](../CONTRIBUTING.md#signing-off-on-commits-developer-certificate-of-origin)**
- [x] Yes, I signed my commits.
<!--
Thank you for contributing to LocalAI!
Contributing Conventions
-------------------------
The draft above helps to give a quick overview of your PR.
Remember to remove this comment and to at least:
1. Include descriptive PR titles with [<component-name>] prepended. We
use [conventional
commits](https://www.conventionalcommits.org/en/v1.0.0/).
2. Build and test your changes before submitting a PR (`make build`).
3. Sign your commits
4. **Tag maintainer:** for a quicker response, tag the relevant
maintainer (see below).
5. **X/Twitter handle:** we announce bigger features on X/Twitter. If
your PR gets announced, and you'd like a mention, we'll gladly shout you
out!
By following the community's contribution conventions upfront, the
review process will
be accelerated and your PR merged more quickly.
If no one reviews your PR within a few days, please @-mention @mudler.
-->
Signed-off-by: GitHub <noreply@github.com>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* feat(conda): Add the seperate conda env for VALL-E X (#1147)
**Description**
This PR is related to #1117
**Notes for Reviewers**
* The gRPC server cannot start up
```
(ttsvalle) @Aisuko ➜ /workspaces/LocalAI (feat/vall-e-x) $ /opt/conda/envs/ttsvalle/bin/python /workspaces/LocalAI/extra/grpc/vall-e-x/ttsvalle.py
Traceback (most recent call last):
File "/workspaces/LocalAI/extra/grpc/vall-e-x/ttsvalle.py", line 14, in <module>
from utils.generation import SAMPLE_RATE, generate_audio, preload_models
ModuleNotFoundError: No module named 'utils'
```
The installation steps follow
https://github.com/Plachtaa/VALL-E-X#-installation below:
* Under the `ttsvalle` conda env
```
git clone https://github.com/Plachtaa/VALL-E-X.git
cd VALL-E-X
pip install -r requirements.txt
```
**[Signed
commits](../CONTRIBUTING.md#signing-off-on-commits-developer-certificate-of-origin)**
- [x] Yes, I signed my commits.
<!--
Thank you for contributing to LocalAI!
Contributing Conventions
-------------------------
The draft above helps to give a quick overview of your PR.
Remember to remove this comment and to at least:
1. Include descriptive PR titles with [<component-name>] prepended. We
use [conventional
commits](https://www.conventionalcommits.org/en/v1.0.0/).
2. Build and test your changes before submitting a PR (`make build`).
3. Sign your commits
4. **Tag maintainer:** for a quicker response, tag the relevant
maintainer (see below).
5. **X/Twitter handle:** we announce bigger features on X/Twitter. If
your PR gets announced, and you'd like a mention, we'll gladly shout you
out!
By following the community's contribution conventions upfront, the
review process will
be accelerated and your PR merged more quickly.
If no one reviews your PR within a few days, please @-mention @mudler.
-->
Signed-off-by: GitHub <noreply@github.com>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* fix: set image type
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* feat(conda):Add seperate conda env for exllama (#1149)
Add seperate env for exllama
Signed-off-by: Aisuko <urakiny@gmail.com>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Setup conda
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Set image_type arg
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* ci: prepare only conda env in tests
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Dockerfile: comment manual pip calls
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* conda: add conda to PATH
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* fixes
* add shebang
* Fixups
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* file perms
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* debug
* Install new conda in the worker
* Disable GPU tests for now until the worker is back
* Rename workflows
* debug
* Fixup conda install
* fixup(wrapper): pass args
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
---------
Signed-off-by: GitHub <noreply@github.com>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Signed-off-by: Aisuko <urakiny@gmail.com>
Signed-off-by: Ettore Di Giacinto <mudler@users.noreply.github.com>
Co-authored-by: Aisuko <urakiny@gmail.com>
2023-11-04 15:30:32 +01:00
wget -q https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin -O test-models/whisper-en
wget -q https://huggingface.co/mudler/all-MiniLM-L6-v2/resolve/main/ggml-model-q4_0.bin -O test-models/bert
wget -q https://cdn.openai.com/whisper/draft-20220913a/micro-machines.wav -O test-dir/audio.wav
2023-05-18 15:59:03 +02:00
cp tests/models_fixtures/* test-models
2023-04-22 00:44:52 +02:00
2025-07-22 16:31:04 +02:00
prepare-test : protogen -go
2023-05-18 15:59:03 +02:00
cp tests/models_fixtures/* test-models
2023-07-15 01:19:43 +02:00
2025-07-18 13:24:12 +02:00
########################################################
## Tests
########################################################
2025-05-04 16:42:42 +02:00
## Test targets
2025-07-22 16:31:04 +02:00
test : test -models /testmodel .ggml protogen -go
2023-07-15 01:19:43 +02:00
@echo 'Running tests'
2025-07-19 08:31:33 +02:00
export GO_TAGS = "debug"
2023-07-15 01:19:43 +02:00
$( MAKE) prepare-test
2026-03-13 20:37:15 +00:00
OPUS_SHIM_LIBRARY = $( abspath ./pkg/opus/shim/libopusshim.so) \
2025-07-18 13:24:12 +02:00
HUGGINGFACE_GRPC = $( abspath ./) /backend/python/transformers/run.sh TEST_DIR = $( abspath ./) /test-dir/ FIXTURES = $( abspath ./) /tests/fixtures CONFIG_FILE = $( abspath ./) /test-models/config.yaml MODELS_PATH = $( abspath ./) /test-models BACKENDS_PATH = $( abspath ./) /backends \
2025-02-06 18:36:23 +01:00
$( GOCMD) run github.com/onsi/ginkgo/v2/ginkgo --label-filter= "!llama-gguf" --flake-attempts $( TEST_FLAKES) --fail-fast -v -r $( TEST_PATHS)
2023-08-24 01:18:58 +02:00
$( MAKE) test-llama-gguf
2023-07-15 01:19:43 +02:00
$( MAKE) test-tts
$( MAKE) test-stablediffusion
2025-07-18 13:24:12 +02:00
########################################################
2026-03-14 17:49:36 +01:00
## E2E AIO tests (uses standard image with pre-configured models)
2025-07-18 13:24:12 +02:00
########################################################
2026-03-14 17:49:36 +01:00
docker-build-e2e :
2026-01-04 21:12:50 +01:00
docker build \
--build-arg MAKEFLAGS = "--jobs=5 --output-sync=target" \
--build-arg BASE_IMAGE = $( BASE_IMAGE) \
--build-arg IMAGE_TYPE = $( IMAGE_TYPE) \
--build-arg BUILD_TYPE = $( BUILD_TYPE) \
--build-arg CUDA_MAJOR_VERSION = $( CUDA_MAJOR_VERSION) \
--build-arg CUDA_MINOR_VERSION = $( CUDA_MINOR_VERSION) \
--build-arg UBUNTU_VERSION = $( UBUNTU_VERSION) \
2026-01-06 14:26:42 +00:00
--build-arg UBUNTU_CODENAME = $( UBUNTU_CODENAME) \
2026-01-04 21:12:50 +01:00
--build-arg GO_TAGS = " $( GO_TAGS) " \
-t local-ai:tests -f Dockerfile .
2025-07-18 13:24:12 +02:00
e2e-aio :
LOCALAI_BACKEND_DIR = $( abspath ./backends) \
2026-03-14 17:49:36 +01:00
LOCALAI_MODELS_DIR = $( abspath ./tests/e2e-aio/models) \
LOCALAI_IMAGE_TAG = tests \
LOCALAI_IMAGE = local-ai \
2025-07-18 13:24:12 +02:00
$( MAKE) run-e2e-aio
run-e2e-aio : protogen -go
@echo 'Running e2e AIO tests'
$( GOCMD) run github.com/onsi/ginkgo/v2/ginkgo --flake-attempts $( TEST_FLAKES) -v -r ./tests/e2e-aio
########################################################
## E2E tests
########################################################
2023-10-19 13:50:40 +02:00
prepare-e2e :
2026-01-04 21:12:50 +01:00
docker build \
--build-arg IMAGE_TYPE = core \
--build-arg BUILD_TYPE = $( BUILD_TYPE) \
--build-arg BASE_IMAGE = $( BASE_IMAGE) \
--build-arg CUDA_MAJOR_VERSION = $( CUDA_MAJOR_VERSION) \
--build-arg CUDA_MINOR_VERSION = $( CUDA_MINOR_VERSION) \
--build-arg UBUNTU_VERSION = $( UBUNTU_VERSION) \
2026-01-06 14:26:42 +00:00
--build-arg UBUNTU_CODENAME = $( UBUNTU_CODENAME) \
2026-01-04 21:12:50 +01:00
--build-arg GO_TAGS = " $( GO_TAGS) " \
--build-arg MAKEFLAGS = " $( DOCKER_MAKEFLAGS) " \
-t localai-tests .
2023-10-19 13:50:40 +02:00
run-e2e-image :
2026-01-30 12:41:50 +01:00
docker run -p 5390:8080 -e MODELS_PATH = /models -e THREADS = 1 -e DEBUG = true -d --rm -v $( TEST_DIR) :/models --name e2e-tests-$( RANDOM) localai-tests
2023-10-19 13:50:40 +02:00
2026-01-30 12:41:50 +01:00
test-e2e : build -mock -backend prepare -e 2e run -e 2e -image
2023-10-19 13:50:40 +02:00
@echo 'Running e2e tests'
BUILD_TYPE = $( BUILD_TYPE) \
2026-01-30 12:41:50 +01:00
LOCALAI_API = http://$( E2E_BRIDGE_IP) :5390 \
2024-10-08 09:24:19 +02:00
$( GOCMD) run github.com/onsi/ginkgo/v2/ginkgo --flake-attempts $( TEST_FLAKES) -v -r ./tests/e2e
2026-01-30 12:41:50 +01:00
$( MAKE) clean-mock-backend
$( MAKE) teardown-e2e
docker rmi localai-tests
2023-10-19 13:50:40 +02:00
teardown-e2e :
rm -rf $( TEST_DIR) || true
docker stop $$ ( docker ps -q --filter ancestor = localai-tests)
2025-07-18 13:24:12 +02:00
########################################################
## Integration and unit tests
########################################################
2023-08-24 01:18:58 +02:00
test-llama-gguf : prepare -test
2025-07-18 13:24:12 +02:00
TEST_DIR = $( abspath ./) /test-dir/ FIXTURES = $( abspath ./) /tests/fixtures CONFIG_FILE = $( abspath ./) /test-models/config.yaml MODELS_PATH = $( abspath ./) /test-models BACKENDS_PATH = $( abspath ./) /backends \
2024-10-08 09:24:19 +02:00
$( GOCMD) run github.com/onsi/ginkgo/v2/ginkgo --label-filter= "llama-gguf" --flake-attempts $( TEST_FLAKES) -v -r $( TEST_PATHS)
2023-08-24 01:18:58 +02:00
2023-07-15 01:19:43 +02:00
test-tts : prepare -test
2025-07-18 13:24:12 +02:00
TEST_DIR = $( abspath ./) /test-dir/ FIXTURES = $( abspath ./) /tests/fixtures CONFIG_FILE = $( abspath ./) /test-models/config.yaml MODELS_PATH = $( abspath ./) /test-models BACKENDS_PATH = $( abspath ./) /backends \
2024-10-08 09:24:19 +02:00
$( GOCMD) run github.com/onsi/ginkgo/v2/ginkgo --label-filter= "tts" --flake-attempts $( TEST_FLAKES) -v -r $( TEST_PATHS)
2023-07-15 01:19:43 +02:00
test-stablediffusion : prepare -test
2025-07-18 13:24:12 +02:00
TEST_DIR = $( abspath ./) /test-dir/ FIXTURES = $( abspath ./) /tests/fixtures CONFIG_FILE = $( abspath ./) /test-models/config.yaml MODELS_PATH = $( abspath ./) /test-models BACKENDS_PATH = $( abspath ./) /backends \
2024-10-08 09:24:19 +02:00
$( GOCMD) run github.com/onsi/ginkgo/v2/ginkgo --label-filter= "stablediffusion" --flake-attempts $( TEST_FLAKES) -v -r $( TEST_PATHS)
2023-07-15 01:19:43 +02:00
2025-07-22 16:31:04 +02:00
test-stores :
2024-10-08 09:24:19 +02:00
$( GOCMD) run github.com/onsi/ginkgo/v2/ginkgo --label-filter= "stores" --flake-attempts $( TEST_FLAKES) -v -r tests/integration
2024-03-22 20:14:04 +00:00
2026-03-13 20:37:15 +00:00
test-opus :
@echo 'Running opus backend tests'
$( MAKE) -C backend/go/opus libopusshim.so
$( GOCMD) run github.com/onsi/ginkgo/v2/ginkgo --flake-attempts $( TEST_FLAKES) -v -r ./backend/go/opus/...
test-opus-docker :
@echo 'Running opus backend tests in Docker'
docker build --target builder \
--build-arg BUILD_TYPE = $( or $( BUILD_TYPE) ,) \
--build-arg BASE_IMAGE = $( or $( BASE_IMAGE) ,ubuntu:24.04) \
--build-arg BACKEND = opus \
-t localai-opus-test -f backend/Dockerfile.golang .
docker run --rm localai-opus-test \
bash -c 'cd /LocalAI && go run github.com/onsi/ginkgo/v2/ginkgo --flake-attempts $(TEST_FLAKES) -v -r ./backend/go/opus/...'
test-realtime : build -mock -backend
@echo 'Running realtime e2e tests (mock backend)'
$( GOCMD) run github.com/onsi/ginkgo/v2/ginkgo --label-filter= "Realtime && !real-models" --flake-attempts $( TEST_FLAKES) -v -r ./tests/e2e
# Real-model realtime tests. Set REALTIME_TEST_MODEL to use your own pipeline,
# or leave unset to auto-build one from the component env vars below.
REALTIME_VAD ?= silero-vad-ggml
REALTIME_STT ?= whisper-1
REALTIME_LLM ?= qwen3-0.6b
REALTIME_TTS ?= tts-1
REALTIME_BACKENDS_PATH ?= $( abspath ./) /backends
test-realtime-models : build -mock -backend
@echo 'Running realtime e2e tests (real models)'
REALTIME_TEST_MODEL = $$ { REALTIME_TEST_MODEL:-realtime-test-pipeline} \
REALTIME_VAD = $( REALTIME_VAD) \
REALTIME_STT = $( REALTIME_STT) \
REALTIME_LLM = $( REALTIME_LLM) \
REALTIME_TTS = $( REALTIME_TTS) \
REALTIME_BACKENDS_PATH = $( REALTIME_BACKENDS_PATH) \
$( GOCMD) run github.com/onsi/ginkgo/v2/ginkgo --label-filter= "Realtime" --flake-attempts $( TEST_FLAKES) -v -r ./tests/e2e
# --- Container-based real-model testing ---
REALTIME_BACKEND_NAMES ?= silero-vad whisper llama-cpp kokoro
REALTIME_MODELS_DIR ?= $( abspath ./models)
REALTIME_BACKENDS_DIR ?= $( abspath ./local-backends)
REALTIME_DOCKER_FLAGS ?= --gpus all
local-backends :
mkdir -p local-backends
extract-backend-% : docker -build -% local -backends
@echo " Extracting backend $* ... "
@CID= $$ ( docker create local-ai-backend:$* ) && \
rm -rf local-backends/$* && mkdir -p local-backends/$* && \
docker cp $$ CID:/ - | tar -xf - -C local-backends/$* && \
docker rm $$ CID > /dev/null
extract-realtime-backends : $( addprefix extract -backend -,$ ( REALTIME_BACKEND_NAMES ) )
test-realtime-models-docker : build -mock -backend
docker build --target build-requirements \
--build-arg BUILD_TYPE = $( or $( BUILD_TYPE) ,cublas) \
--build-arg CUDA_MAJOR_VERSION = $( or $( CUDA_MAJOR_VERSION) ,13) \
--build-arg CUDA_MINOR_VERSION = $( or $( CUDA_MINOR_VERSION) ,0) \
-t localai-test-runner .
docker run --rm \
$( REALTIME_DOCKER_FLAGS) \
-v $( abspath ./) :/build \
-v $( REALTIME_MODELS_DIR) :/models:ro \
-v $( REALTIME_BACKENDS_DIR) :/backends \
-v localai-go-cache:/root/go/pkg/mod \
-v localai-go-build-cache:/root/.cache/go-build \
-e REALTIME_TEST_MODEL = $$ { REALTIME_TEST_MODEL:-realtime-test-pipeline} \
-e REALTIME_VAD = $( REALTIME_VAD) \
-e REALTIME_STT = $( REALTIME_STT) \
-e REALTIME_LLM = $( REALTIME_LLM) \
-e REALTIME_TTS = $( REALTIME_TTS) \
-e REALTIME_BACKENDS_PATH = /backends \
-e REALTIME_MODELS_PATH = /models \
-w /build \
localai-test-runner \
bash -c 'git config --global --add safe.directory /build && \
make protogen-go && make build-mock-backend && \
go run github.com/onsi/ginkgo/v2/ginkgo --label-filter="Realtime" --flake-attempts $(TEST_FLAKES) -v -r ./tests/e2e'
2023-07-15 01:19:43 +02:00
test-container :
docker build --target requirements -t local-ai-test-container .
2023-07-20 22:10:42 +02:00
docker run -ti --rm --entrypoint /bin/bash -ti -v $( abspath ./) :/build local-ai-test-container
2023-04-15 16:39:07 -07:00
2025-07-18 13:24:12 +02:00
########################################################
## Help
########################################################
2023-04-15 16:39:07 -07:00
## Help:
help : ## Show this help.
@echo ''
@echo 'Usage:'
@echo ' ${YELLOW}make${RESET} ${GREEN}<target>${RESET}'
@echo ''
@echo 'Targets:'
@awk 'BEGIN {FS = ":.*?## "} { \
if (/^[a-zA-Z_-]+:.*?##.*$$/) {printf " ${YELLOW}%-20s${GREEN}%s${RESET}\n", $$1, $$2} \
else if (/^## .*$$/) {printf " ${CYAN}%s${RESET}\n", substr($$1,4)} \
2023-04-17 21:34:02 +02:00
}' $( MAKEFILE_LIST)
2023-07-15 01:19:43 +02:00
2025-07-18 13:24:12 +02:00
########################################################
## Backends
########################################################
2024-04-13 02:37:32 -05:00
.PHONY : protogen
2025-07-24 14:49:50 +02:00
protogen : protogen -go
2024-04-13 02:37:32 -05:00
2025-07-22 16:31:04 +02:00
protoc :
@OS_NAME= $$ ( uname -s | tr '[:upper:]' '[:lower:]' ) ; \
ARCH_NAME = $$ ( uname -m) ; \
if [ " $$ OS_NAME " = "darwin" ] ; then \
if [ " $$ ARCH_NAME " = "arm64" ] ; then \
FILE = protoc-31.1-osx-aarch_64.zip; \
elif [ " $$ ARCH_NAME " = "x86_64" ] ; then \
FILE = protoc-31.1-osx-x86_64.zip; \
else \
echo " Unsupported macOS architecture: $$ ARCH_NAME " ; exit 1; \
fi ; \
elif [ " $$ OS_NAME " = "linux" ] ; then \
if [ " $$ ARCH_NAME " = "x86_64" ] ; then \
FILE = protoc-31.1-linux-x86_64.zip; \
elif [ " $$ ARCH_NAME " = "aarch64" ] || [ " $$ ARCH_NAME " = "arm64" ] ; then \
FILE = protoc-31.1-linux-aarch_64.zip; \
elif [ " $$ ARCH_NAME " = "ppc64le" ] ; then \
FILE = protoc-31.1-linux-ppcle_64.zip; \
elif [ " $$ ARCH_NAME " = "s390x" ] ; then \
FILE = protoc-31.1-linux-s390_64.zip; \
elif [ " $$ ARCH_NAME " = "i386" ] || [ " $$ ARCH_NAME " = "x86" ] ; then \
FILE = protoc-31.1-linux-x86_32.zip; \
else \
echo " Unsupported Linux architecture: $$ ARCH_NAME " ; exit 1; \
fi ; \
else \
echo " Unsupported OS: $$ OS_NAME " ; exit 1; \
fi ; \
URL = https://github.com/protocolbuffers/protobuf/releases/download/v31.1/$$ FILE; \
2025-12-11 20:32:25 +01:00
curl -L $$ URL -o protoc.zip && \
2025-07-22 16:31:04 +02:00
unzip -j -d $( CURDIR) protoc.zip bin/protoc && rm protoc.zip
2024-04-13 02:37:32 -05:00
.PHONY : protogen -go
2025-07-22 16:31:04 +02:00
protogen-go : protoc install -go -tools
2024-04-13 02:37:32 -05:00
mkdir -p pkg/grpc/proto
2025-07-22 16:31:04 +02:00
./protoc --experimental_allow_proto3_optional -Ibackend/ --go_out= pkg/grpc/proto/ --go_opt= paths = source_relative --go-grpc_out= pkg/grpc/proto/ --go-grpc_opt= paths = source_relative \
2023-11-13 22:40:16 +01:00
backend/backend.proto
2023-07-15 01:19:43 +02:00
2026-03-22 00:57:15 +01:00
core/config/inference_defaults.json : ## Fetch inference defaults from unsloth (only if missing)
$( GOCMD) generate ./core/config/...
.PHONY : generate
generate : core /config /inference_defaults .json ## Ensure inference defaults exist
.PHONY : generate -force
generate-force : ## Re-fetch inference defaults from unsloth (always)
$( GOCMD) generate ./core/config/...
2024-04-13 02:37:32 -05:00
.PHONY : protogen -go -clean
protogen-go-clean :
$( RM) pkg/grpc/proto/backend.pb.go pkg/grpc/proto/backend_grpc.pb.go
$( RM) bin/*
prepare-test-extra : protogen -python
2023-12-08 15:45:04 +01:00
$( MAKE) -C backend/python/transformers
2026-02-03 21:57:50 +01:00
$( MAKE) -C backend/python/outetts
2023-12-11 02:20:34 -05:00
$( MAKE) -C backend/python/diffusers
2025-05-30 10:52:55 +02:00
$( MAKE) -C backend/python/chatterbox
2025-04-30 08:55:07 -04:00
$( MAKE) -C backend/python/vllm
2026-01-24 22:23:30 +01:00
$( MAKE) -C backend/python/vllm-omni
2025-12-10 21:14:21 +01:00
$( MAKE) -C backend/python/vibevoice
2026-01-07 21:44:35 +01:00
$( MAKE) -C backend/python/moonshine
2026-01-13 23:35:19 +01:00
$( MAKE) -C backend/python/pocket-tts
2026-01-23 15:18:41 +01:00
$( MAKE) -C backend/python/qwen-tts
2026-03-12 07:48:23 +01:00
$( MAKE) -C backend/python/fish-speech
2026-02-27 08:16:51 +01:00
$( MAKE) -C backend/python/faster-qwen3-tts
2026-01-29 21:50:35 +01:00
$( MAKE) -C backend/python/qwen-asr
2026-02-07 08:19:37 +01:00
$( MAKE) -C backend/python/nemo
2026-01-28 14:44:04 +01:00
$( MAKE) -C backend/python/voxcpm
feat(whisperx): add whisperx backend for transcription with speaker diarization (#8299)
* feat(proto): add speaker field to TranscriptSegment for diarization
Add speaker field to the gRPC TranscriptSegment message and map it
through the Go schema, enabling backends to return speaker labels.
Signed-off-by: eureka928 <meobius123@gmail.com>
* feat(whisperx): add whisperx backend for transcription with diarization
Add Python gRPC backend using WhisperX for speech-to-text with
word-level timestamps, forced alignment, and speaker diarization
via pyannote-audio when HF_TOKEN is provided.
Signed-off-by: eureka928 <meobius123@gmail.com>
* feat(whisperx): register whisperx backend in Makefile
Signed-off-by: eureka928 <meobius123@gmail.com>
* feat(whisperx): add whisperx meta and image entries to index.yaml
Signed-off-by: eureka928 <meobius123@gmail.com>
* ci(whisperx): add build matrix entries for CPU, CUDA 12/13, and ROCm
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(whisperx): unpin torch versions and use CPU index for cpu requirements
Address review feedback:
- Use --extra-index-url for CPU torch wheels to reduce size
- Remove torch version pins, let uv resolve compatible versions
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(whisperx): pin torch ROCm variant to fix CI build failure
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(whisperx): pin torch CPU variant to fix uv resolution failure
Pin torch==2.8.0+cpu so uv resolves the CPU wheel from the extra
index instead of picking torch==2.8.0+cu128 from PyPI, which pulls
unresolvable CUDA dependencies.
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(whisperx): use unsafe-best-match index strategy to fix uv resolution failure
uv's default first-match strategy finds torch on PyPI before checking
the extra index, causing it to pick torch==2.8.0+cu128 instead of the
CPU variant. This makes whisperx's transitive torch dependency
unresolvable. Using unsafe-best-match lets uv consider all indexes.
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(whisperx): drop +cpu local version suffix to fix uv resolution failure
PEP 440 ==2.8.0 matches 2.8.0+cpu from the extra index, avoiding the
issue where uv cannot locate an explicit +cpu local version specifier.
This aligns with the pattern used by all other CPU backends.
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(backends): drop +rocm local version suffixes from hipblas requirements to fix uv resolution
uv cannot resolve PEP 440 local version specifiers (e.g. +rocm6.4,
+rocm6.3) in pinned requirements. The --extra-index-url already points
to the correct ROCm wheel index and --index-strategy unsafe-best-match
(set in libbackend.sh) ensures the ROCm variant is preferred.
Applies the same fix as 7f5d72e8 (which resolved this for +cpu) across
all 14 hipblas requirements files.
Signed-off-by: eureka928 <meobius123@gmail.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: eureka928 <meobius123@gmail.com>
* revert: scope hipblas suffix fix to whisperx only
Reverts changes to non-whisperx hipblas requirements files per
maintainer review — other backends are building fine with the +rocm
local version suffix.
Signed-off-by: eureka928 <meobius123@gmail.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: eureka928 <meobius123@gmail.com>
---------
Signed-off-by: eureka928 <meobius123@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 10:33:12 -05:00
$( MAKE) -C backend/python/whisperx
2026-02-05 12:04:53 +01:00
$( MAKE) -C backend/python/ace-step
2026-03-21 02:08:02 +01:00
$( MAKE) -C backend/python/trl
2023-12-08 15:45:04 +01:00
test-extra : prepare -test -extra
$( MAKE) -C backend/python/transformers test
2026-02-03 21:57:50 +01:00
$( MAKE) -C backend/python/outetts test
2023-12-11 02:20:34 -05:00
$( MAKE) -C backend/python/diffusers test
2025-05-30 10:52:55 +02:00
$( MAKE) -C backend/python/chatterbox test
2025-04-30 08:55:07 -04:00
$( MAKE) -C backend/python/vllm test
2026-01-24 22:23:30 +01:00
$( MAKE) -C backend/python/vllm-omni test
2025-12-10 21:14:21 +01:00
$( MAKE) -C backend/python/vibevoice test
2026-01-07 21:44:35 +01:00
$( MAKE) -C backend/python/moonshine test
2026-01-13 23:35:19 +01:00
$( MAKE) -C backend/python/pocket-tts test
2026-01-23 15:18:41 +01:00
$( MAKE) -C backend/python/qwen-tts test
2026-03-12 07:48:23 +01:00
$( MAKE) -C backend/python/fish-speech test
2026-02-27 08:16:51 +01:00
$( MAKE) -C backend/python/faster-qwen3-tts test
2026-01-29 21:50:35 +01:00
$( MAKE) -C backend/python/qwen-asr test
2026-02-07 08:19:37 +01:00
$( MAKE) -C backend/python/nemo test
2026-01-28 14:44:04 +01:00
$( MAKE) -C backend/python/voxcpm test
feat(whisperx): add whisperx backend for transcription with speaker diarization (#8299)
* feat(proto): add speaker field to TranscriptSegment for diarization
Add speaker field to the gRPC TranscriptSegment message and map it
through the Go schema, enabling backends to return speaker labels.
Signed-off-by: eureka928 <meobius123@gmail.com>
* feat(whisperx): add whisperx backend for transcription with diarization
Add Python gRPC backend using WhisperX for speech-to-text with
word-level timestamps, forced alignment, and speaker diarization
via pyannote-audio when HF_TOKEN is provided.
Signed-off-by: eureka928 <meobius123@gmail.com>
* feat(whisperx): register whisperx backend in Makefile
Signed-off-by: eureka928 <meobius123@gmail.com>
* feat(whisperx): add whisperx meta and image entries to index.yaml
Signed-off-by: eureka928 <meobius123@gmail.com>
* ci(whisperx): add build matrix entries for CPU, CUDA 12/13, and ROCm
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(whisperx): unpin torch versions and use CPU index for cpu requirements
Address review feedback:
- Use --extra-index-url for CPU torch wheels to reduce size
- Remove torch version pins, let uv resolve compatible versions
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(whisperx): pin torch ROCm variant to fix CI build failure
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(whisperx): pin torch CPU variant to fix uv resolution failure
Pin torch==2.8.0+cpu so uv resolves the CPU wheel from the extra
index instead of picking torch==2.8.0+cu128 from PyPI, which pulls
unresolvable CUDA dependencies.
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(whisperx): use unsafe-best-match index strategy to fix uv resolution failure
uv's default first-match strategy finds torch on PyPI before checking
the extra index, causing it to pick torch==2.8.0+cu128 instead of the
CPU variant. This makes whisperx's transitive torch dependency
unresolvable. Using unsafe-best-match lets uv consider all indexes.
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(whisperx): drop +cpu local version suffix to fix uv resolution failure
PEP 440 ==2.8.0 matches 2.8.0+cpu from the extra index, avoiding the
issue where uv cannot locate an explicit +cpu local version specifier.
This aligns with the pattern used by all other CPU backends.
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(backends): drop +rocm local version suffixes from hipblas requirements to fix uv resolution
uv cannot resolve PEP 440 local version specifiers (e.g. +rocm6.4,
+rocm6.3) in pinned requirements. The --extra-index-url already points
to the correct ROCm wheel index and --index-strategy unsafe-best-match
(set in libbackend.sh) ensures the ROCm variant is preferred.
Applies the same fix as 7f5d72e8 (which resolved this for +cpu) across
all 14 hipblas requirements files.
Signed-off-by: eureka928 <meobius123@gmail.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: eureka928 <meobius123@gmail.com>
* revert: scope hipblas suffix fix to whisperx only
Reverts changes to non-whisperx hipblas requirements files per
maintainer review — other backends are building fine with the +rocm
local version suffix.
Signed-off-by: eureka928 <meobius123@gmail.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: eureka928 <meobius123@gmail.com>
---------
Signed-off-by: eureka928 <meobius123@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 10:33:12 -05:00
$( MAKE) -C backend/python/whisperx test
2026-02-05 12:04:53 +01:00
$( MAKE) -C backend/python/ace-step test
2026-03-21 02:08:02 +01:00
$( MAKE) -C backend/python/trl test
feat(conda): conda environments (#1144)
* feat(autogptq): add a separate conda environment for autogptq (#1137)
**Description**
This PR related to #1117
**Notes for Reviewers**
Here we lock down the version of the dependencies. Make sure it can be
used all the time without failed if the version of dependencies were
upgraded.
I change the order of importing packages according to the pylint, and no
change the logic of code. It should be ok.
I will do more investigate on writing some test cases for every backend.
I can run the service in my environment, but there is not exist a way to
test it. So, I am not confident on it.
Add a README.md in the `grpc` root. This is the common commands for
creating `conda` environment. And it can be used to the reference file
for creating extral gRPC backend document.
Signed-off-by: GitHub <noreply@github.com>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* [Extra backend] Add seperate environment for ttsbark (#1141)
**Description**
This PR relates to #1117
**Notes for Reviewers**
Same to the latest PR:
* The code is also changed, but only the order of the import package
parts. And some code comments are also added.
* Add a configuration of the `conda` environment
* Add a simple test case for testing if the service can be startup in
current `conda` environment. It is succeed in VSCode, but the it is not
out of box on terminal. So, it is hard to say the test case really
useful.
**[Signed
commits](../CONTRIBUTING.md#signing-off-on-commits-developer-certificate-of-origin)**
- [x] Yes, I signed my commits.
<!--
Thank you for contributing to LocalAI!
Contributing Conventions
-------------------------
The draft above helps to give a quick overview of your PR.
Remember to remove this comment and to at least:
1. Include descriptive PR titles with [<component-name>] prepended. We
use [conventional
commits](https://www.conventionalcommits.org/en/v1.0.0/).
2. Build and test your changes before submitting a PR (`make build`).
3. Sign your commits
4. **Tag maintainer:** for a quicker response, tag the relevant
maintainer (see below).
5. **X/Twitter handle:** we announce bigger features on X/Twitter. If
your PR gets announced, and you'd like a mention, we'll gladly shout you
out!
By following the community's contribution conventions upfront, the
review process will
be accelerated and your PR merged more quickly.
If no one reviews your PR within a few days, please @-mention @mudler.
-->
Signed-off-by: GitHub <noreply@github.com>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* feat(conda): add make target and entrypoints for the dockerfile
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* feat(conda): Add seperate conda env for diffusers (#1145)
**Description**
This PR relates to #1117
**Notes for Reviewers**
* Add `conda` env `diffusers.yml`
* Add Makefile to create it automatically
* Add `run.sh` to support running as a extra backend
* Also adding it to the main Dockerfile
* Add make command in the root Makefile
* Testing the server, it can start up under the env
Signed-off-by: GitHub <noreply@github.com>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* feat(conda):Add seperate env for vllm (#1148)
**Description**
This PR is related to #1117
**Notes for Reviewers**
* The gRPC server can be started as normal
* The test case can be triggered in VSCode
* Same to other this kind of PRs, add `vllm.yml` Makefile and add
`run.sh` to the main Dockerfile, and command to the main Makefile
**[Signed
commits](../CONTRIBUTING.md#signing-off-on-commits-developer-certificate-of-origin)**
- [x] Yes, I signed my commits.
<!--
Thank you for contributing to LocalAI!
Contributing Conventions
-------------------------
The draft above helps to give a quick overview of your PR.
Remember to remove this comment and to at least:
1. Include descriptive PR titles with [<component-name>] prepended. We
use [conventional
commits](https://www.conventionalcommits.org/en/v1.0.0/).
2. Build and test your changes before submitting a PR (`make build`).
3. Sign your commits
4. **Tag maintainer:** for a quicker response, tag the relevant
maintainer (see below).
5. **X/Twitter handle:** we announce bigger features on X/Twitter. If
your PR gets announced, and you'd like a mention, we'll gladly shout you
out!
By following the community's contribution conventions upfront, the
review process will
be accelerated and your PR merged more quickly.
If no one reviews your PR within a few days, please @-mention @mudler.
-->
Signed-off-by: GitHub <noreply@github.com>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* feat(conda):Add seperate env for huggingface (#1146)
**Description**
This PR is related to #1117
**Notes for Reviewers**
* Add conda env `huggingface.yml`
* Change the import order, and also remove the no-used packages
* Add `run.sh` and `make command` to the main Dockerfile and Makefile
* Add test cases for it. It can be triggered and succeed under VSCode
Python extension but it is hang by using `python -m unites
test_huggingface.py` in the terminal
```
Running tests (unittest): /workspaces/LocalAI/extra/grpc/huggingface
Running tests: /workspaces/LocalAI/extra/grpc/huggingface/test_huggingface.py::TestBackendServicer::test_embedding
/workspaces/LocalAI/extra/grpc/huggingface/test_huggingface.py::TestBackendServicer::test_load_model
/workspaces/LocalAI/extra/grpc/huggingface/test_huggingface.py::TestBackendServicer::test_server_startup
./test_huggingface.py::TestBackendServicer::test_embedding Passed
./test_huggingface.py::TestBackendServicer::test_load_model Passed
./test_huggingface.py::TestBackendServicer::test_server_startup Passed
Total number of tests expected to run: 3
Total number of tests run: 3
Total number of tests passed: 3
Total number of tests failed: 0
Total number of tests failed with errors: 0
Total number of tests skipped: 0
Finished running tests!
```
**[Signed
commits](../CONTRIBUTING.md#signing-off-on-commits-developer-certificate-of-origin)**
- [x] Yes, I signed my commits.
<!--
Thank you for contributing to LocalAI!
Contributing Conventions
-------------------------
The draft above helps to give a quick overview of your PR.
Remember to remove this comment and to at least:
1. Include descriptive PR titles with [<component-name>] prepended. We
use [conventional
commits](https://www.conventionalcommits.org/en/v1.0.0/).
2. Build and test your changes before submitting a PR (`make build`).
3. Sign your commits
4. **Tag maintainer:** for a quicker response, tag the relevant
maintainer (see below).
5. **X/Twitter handle:** we announce bigger features on X/Twitter. If
your PR gets announced, and you'd like a mention, we'll gladly shout you
out!
By following the community's contribution conventions upfront, the
review process will
be accelerated and your PR merged more quickly.
If no one reviews your PR within a few days, please @-mention @mudler.
-->
Signed-off-by: GitHub <noreply@github.com>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* feat(conda): Add the seperate conda env for VALL-E X (#1147)
**Description**
This PR is related to #1117
**Notes for Reviewers**
* The gRPC server cannot start up
```
(ttsvalle) @Aisuko ➜ /workspaces/LocalAI (feat/vall-e-x) $ /opt/conda/envs/ttsvalle/bin/python /workspaces/LocalAI/extra/grpc/vall-e-x/ttsvalle.py
Traceback (most recent call last):
File "/workspaces/LocalAI/extra/grpc/vall-e-x/ttsvalle.py", line 14, in <module>
from utils.generation import SAMPLE_RATE, generate_audio, preload_models
ModuleNotFoundError: No module named 'utils'
```
The installation steps follow
https://github.com/Plachtaa/VALL-E-X#-installation below:
* Under the `ttsvalle` conda env
```
git clone https://github.com/Plachtaa/VALL-E-X.git
cd VALL-E-X
pip install -r requirements.txt
```
**[Signed
commits](../CONTRIBUTING.md#signing-off-on-commits-developer-certificate-of-origin)**
- [x] Yes, I signed my commits.
<!--
Thank you for contributing to LocalAI!
Contributing Conventions
-------------------------
The draft above helps to give a quick overview of your PR.
Remember to remove this comment and to at least:
1. Include descriptive PR titles with [<component-name>] prepended. We
use [conventional
commits](https://www.conventionalcommits.org/en/v1.0.0/).
2. Build and test your changes before submitting a PR (`make build`).
3. Sign your commits
4. **Tag maintainer:** for a quicker response, tag the relevant
maintainer (see below).
5. **X/Twitter handle:** we announce bigger features on X/Twitter. If
your PR gets announced, and you'd like a mention, we'll gladly shout you
out!
By following the community's contribution conventions upfront, the
review process will
be accelerated and your PR merged more quickly.
If no one reviews your PR within a few days, please @-mention @mudler.
-->
Signed-off-by: GitHub <noreply@github.com>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* fix: set image type
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* feat(conda):Add seperate conda env for exllama (#1149)
Add seperate env for exllama
Signed-off-by: Aisuko <urakiny@gmail.com>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Setup conda
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Set image_type arg
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* ci: prepare only conda env in tests
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Dockerfile: comment manual pip calls
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* conda: add conda to PATH
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* fixes
* add shebang
* Fixups
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* file perms
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* debug
* Install new conda in the worker
* Disable GPU tests for now until the worker is back
* Rename workflows
* debug
* Fixup conda install
* fixup(wrapper): pass args
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
---------
Signed-off-by: GitHub <noreply@github.com>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Signed-off-by: Aisuko <urakiny@gmail.com>
Signed-off-by: Ettore Di Giacinto <mudler@users.noreply.github.com>
Co-authored-by: Aisuko <urakiny@gmail.com>
2023-11-04 15:30:32 +01:00
2024-02-08 20:12:51 +01:00
DOCKER_IMAGE ?= local-ai
IMAGE_TYPE ?= core
2026-01-06 14:26:42 +00:00
BASE_IMAGE ?= ubuntu:24.04
2024-02-08 20:12:51 +01:00
docker :
docker build \
--build-arg BASE_IMAGE = $( BASE_IMAGE) \
--build-arg IMAGE_TYPE = $( IMAGE_TYPE) \
2024-03-27 15:12:19 -05:00
--build-arg GO_TAGS = " $( GO_TAGS) " \
2024-03-29 16:32:40 -05:00
--build-arg MAKEFLAGS = " $( DOCKER_MAKEFLAGS) " \
2024-02-08 20:12:51 +01:00
--build-arg BUILD_TYPE = $( BUILD_TYPE) \
2026-01-04 21:12:50 +01:00
--build-arg CUDA_MAJOR_VERSION = $( CUDA_MAJOR_VERSION) \
--build-arg CUDA_MINOR_VERSION = $( CUDA_MINOR_VERSION) \
--build-arg UBUNTU_VERSION = $( UBUNTU_VERSION) \
2026-01-06 14:26:42 +00:00
--build-arg UBUNTU_CODENAME = $( UBUNTU_CODENAME) \
2024-02-08 20:12:51 +01:00
-t $( DOCKER_IMAGE) .
2024-05-13 02:37:52 -07:00
2026-01-06 14:26:42 +00:00
docker-cuda12 :
2024-06-19 17:50:49 +02:00
docker build \
2026-01-06 14:26:42 +00:00
--build-arg CUDA_MAJOR_VERSION = ${ CUDA_MAJOR_VERSION } \
--build-arg CUDA_MINOR_VERSION = ${ CUDA_MINOR_VERSION } \
2024-06-19 17:50:49 +02:00
--build-arg BASE_IMAGE = $( BASE_IMAGE) \
--build-arg IMAGE_TYPE = $( IMAGE_TYPE) \
--build-arg GO_TAGS = " $( GO_TAGS) " \
--build-arg MAKEFLAGS = " $( DOCKER_MAKEFLAGS) " \
--build-arg BUILD_TYPE = $( BUILD_TYPE) \
2026-01-04 21:12:50 +01:00
--build-arg UBUNTU_VERSION = $( UBUNTU_VERSION) \
2026-01-06 14:26:42 +00:00
--build-arg UBUNTU_CODENAME = $( UBUNTU_CODENAME) \
-t $( DOCKER_IMAGE) -cuda-12 .
2024-06-19 17:50:49 +02:00
2024-02-08 20:12:51 +01:00
docker-image-intel :
docker build \
2026-01-06 14:26:42 +00:00
--build-arg BASE_IMAGE = intel/oneapi-basekit:2025.3.0-0-devel-ubuntu24.04 \
2024-03-07 14:37:45 +01:00
--build-arg IMAGE_TYPE = $( IMAGE_TYPE) \
2025-05-25 21:25:05 +01:00
--build-arg GO_TAGS = " $( GO_TAGS) " \
2024-03-29 16:32:40 -05:00
--build-arg MAKEFLAGS = " $( DOCKER_MAKEFLAGS) " \
2026-01-04 21:12:50 +01:00
--build-arg BUILD_TYPE = intel \
--build-arg CUDA_MAJOR_VERSION = $( CUDA_MAJOR_VERSION) \
--build-arg CUDA_MINOR_VERSION = $( CUDA_MINOR_VERSION) \
--build-arg UBUNTU_VERSION = $( UBUNTU_VERSION) \
2026-01-06 14:26:42 +00:00
--build-arg UBUNTU_CODENAME = $( UBUNTU_CODENAME) \
2026-01-04 21:12:50 +01:00
-t $( DOCKER_IMAGE) .
2024-03-29 22:29:33 +01:00
2025-07-18 13:24:12 +02:00
########################################################
## Backends
########################################################
2026-01-04 21:12:50 +01:00
# Pattern rule for standard backends (docker-based)
# This matches all backends that use docker-build-* and docker-save-*
backends/% : docker -build -% docker -save -% build
./local-ai backends install " ocifile:// $( abspath ./backend-images/$* .tar) "
2025-08-22 08:42:29 +02:00
2026-01-04 21:12:50 +01:00
# Darwin-specific backends (keep as explicit targets since they have special build logic)
2025-08-22 08:42:29 +02:00
backends/llama-cpp-darwin : build
bash ./scripts/build/llama-cpp-darwin.sh
./local-ai backends install " ocifile:// $( abspath ./backend-images/llama-cpp.tar) "
2025-08-22 08:52:29 +02:00
build-darwin-python-backend : build
2025-08-22 08:42:29 +02:00
bash ./scripts/build/python-darwin.sh
2025-09-01 21:18:30 +01:00
build-darwin-go-backend : build
bash ./scripts/build/golang-darwin.sh
2025-08-22 08:52:29 +02:00
backends/mlx :
2025-08-23 23:05:30 +02:00
BACKEND = mlx $( MAKE) build-darwin-python-backend
2025-08-22 08:42:29 +02:00
./local-ai backends install " ocifile:// $( abspath ./backend-images/mlx.tar) "
2025-08-22 23:14:54 +02:00
backends/diffuser-darwin :
2025-08-23 23:05:30 +02:00
BACKEND = diffusers $( MAKE) build-darwin-python-backend
2025-08-22 23:14:54 +02:00
./local-ai backends install " ocifile:// $( abspath ./backend-images/diffusers.tar) "
2025-08-23 23:05:30 +02:00
backends/mlx-vlm :
BACKEND = mlx-vlm $( MAKE) build-darwin-python-backend
./local-ai backends install " ocifile:// $( abspath ./backend-images/mlx-vlm.tar) "
2025-08-26 15:27:06 +02:00
backends/mlx-audio :
BACKEND = mlx-audio $( MAKE) build-darwin-python-backend
./local-ai backends install " ocifile:// $( abspath ./backend-images/mlx-audio.tar) "
2026-03-09 17:29:32 +01:00
backends/mlx-distributed :
BACKEND = mlx-distributed $( MAKE) build-darwin-python-backend
./local-ai backends install " ocifile:// $( abspath ./backend-images/mlx-distributed.tar) "
2025-09-01 21:18:30 +01:00
backends/stablediffusion-ggml-darwin :
BACKEND = stablediffusion-ggml BUILD_TYPE = metal $( MAKE) build-darwin-go-backend
./local-ai backends install " ocifile:// $( abspath ./backend-images/stablediffusion-ggml.tar) "
2025-07-18 13:24:12 +02:00
backend-images :
mkdir -p backend-images
2026-01-04 21:12:50 +01:00
# Backend metadata: BACKEND_NAME | DOCKERFILE_TYPE | BUILD_CONTEXT | PROGRESS_FLAG | NEEDS_BACKEND_ARG
# llama-cpp is special - uses llama-cpp Dockerfile and doesn't need BACKEND arg
BACKEND_LLAMA_CPP = llama-cpp| llama-cpp| .| false| false
# Golang backends
BACKEND_PIPER = piper| golang| .| false| true
BACKEND_LOCAL_STORE = local-store| golang| .| false| true
BACKEND_HUGGINGFACE = huggingface| golang| .| false| true
BACKEND_SILERO_VAD = silero-vad| golang| .| false| true
BACKEND_STABLEDIFFUSION_GGML = stablediffusion-ggml| golang| .| --progress= plain| true
BACKEND_WHISPER = whisper| golang| .| false| true
2026-02-09 09:12:05 +01:00
BACKEND_VOXTRAL = voxtral| golang| .| false| true
2026-03-12 18:56:26 +01:00
BACKEND_ACESTEP_CPP = acestep-cpp| golang| .| false| true
2026-03-13 20:37:15 +00:00
BACKEND_OPUS = opus| golang| .| false| true
2026-01-04 21:12:50 +01:00
# Python backends with root context
BACKEND_RERANKERS = rerankers| python| .| false| true
BACKEND_TRANSFORMERS = transformers| python| .| false| true
2026-02-03 21:57:50 +01:00
BACKEND_OUTETTS = outetts| python| .| false| true
2026-01-04 21:12:50 +01:00
BACKEND_FASTER_WHISPER = faster-whisper| python| .| false| true
BACKEND_COQUI = coqui| python| .| false| true
2026-01-13 23:35:19 +01:00
BACKEND_RFDETR = rfdetr| python| .| false| true
BACKEND_KITTEN_TTS = kitten-tts| python| .| false| true
BACKEND_NEUTTS = neutts| python| .| false| true
BACKEND_KOKORO = kokoro| python| .| false| true
BACKEND_VLLM = vllm| python| .| false| true
2026-01-24 22:23:30 +01:00
BACKEND_VLLM_OMNI = vllm-omni| python| .| false| true
2026-01-13 23:35:19 +01:00
BACKEND_DIFFUSERS = diffusers| python| .| --progress= plain| true
BACKEND_CHATTERBOX = chatterbox| python| .| false| true
BACKEND_VIBEVOICE = vibevoice| python| .| --progress= plain| true
BACKEND_MOONSHINE = moonshine| python| .| false| true
BACKEND_POCKET_TTS = pocket-tts| python| .| false| true
2026-01-23 15:18:41 +01:00
BACKEND_QWEN_TTS = qwen-tts| python| .| false| true
2026-03-12 07:48:23 +01:00
BACKEND_FISH_SPEECH = fish-speech| python| .| false| true
2026-02-27 08:16:51 +01:00
BACKEND_FASTER_QWEN3_TTS = faster-qwen3-tts| python| .| false| true
2026-01-29 21:50:35 +01:00
BACKEND_QWEN_ASR = qwen-asr| python| .| false| true
2026-02-07 08:19:37 +01:00
BACKEND_NEMO = nemo| python| .| false| true
2026-01-28 14:44:04 +01:00
BACKEND_VOXCPM = voxcpm| python| .| false| true
feat(whisperx): add whisperx backend for transcription with speaker diarization (#8299)
* feat(proto): add speaker field to TranscriptSegment for diarization
Add speaker field to the gRPC TranscriptSegment message and map it
through the Go schema, enabling backends to return speaker labels.
Signed-off-by: eureka928 <meobius123@gmail.com>
* feat(whisperx): add whisperx backend for transcription with diarization
Add Python gRPC backend using WhisperX for speech-to-text with
word-level timestamps, forced alignment, and speaker diarization
via pyannote-audio when HF_TOKEN is provided.
Signed-off-by: eureka928 <meobius123@gmail.com>
* feat(whisperx): register whisperx backend in Makefile
Signed-off-by: eureka928 <meobius123@gmail.com>
* feat(whisperx): add whisperx meta and image entries to index.yaml
Signed-off-by: eureka928 <meobius123@gmail.com>
* ci(whisperx): add build matrix entries for CPU, CUDA 12/13, and ROCm
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(whisperx): unpin torch versions and use CPU index for cpu requirements
Address review feedback:
- Use --extra-index-url for CPU torch wheels to reduce size
- Remove torch version pins, let uv resolve compatible versions
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(whisperx): pin torch ROCm variant to fix CI build failure
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(whisperx): pin torch CPU variant to fix uv resolution failure
Pin torch==2.8.0+cpu so uv resolves the CPU wheel from the extra
index instead of picking torch==2.8.0+cu128 from PyPI, which pulls
unresolvable CUDA dependencies.
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(whisperx): use unsafe-best-match index strategy to fix uv resolution failure
uv's default first-match strategy finds torch on PyPI before checking
the extra index, causing it to pick torch==2.8.0+cu128 instead of the
CPU variant. This makes whisperx's transitive torch dependency
unresolvable. Using unsafe-best-match lets uv consider all indexes.
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(whisperx): drop +cpu local version suffix to fix uv resolution failure
PEP 440 ==2.8.0 matches 2.8.0+cpu from the extra index, avoiding the
issue where uv cannot locate an explicit +cpu local version specifier.
This aligns with the pattern used by all other CPU backends.
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(backends): drop +rocm local version suffixes from hipblas requirements to fix uv resolution
uv cannot resolve PEP 440 local version specifiers (e.g. +rocm6.4,
+rocm6.3) in pinned requirements. The --extra-index-url already points
to the correct ROCm wheel index and --index-strategy unsafe-best-match
(set in libbackend.sh) ensures the ROCm variant is preferred.
Applies the same fix as 7f5d72e8 (which resolved this for +cpu) across
all 14 hipblas requirements files.
Signed-off-by: eureka928 <meobius123@gmail.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: eureka928 <meobius123@gmail.com>
* revert: scope hipblas suffix fix to whisperx only
Reverts changes to non-whisperx hipblas requirements files per
maintainer review — other backends are building fine with the +rocm
local version suffix.
Signed-off-by: eureka928 <meobius123@gmail.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: eureka928 <meobius123@gmail.com>
---------
Signed-off-by: eureka928 <meobius123@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 10:33:12 -05:00
BACKEND_WHISPERX = whisperx| python| .| false| true
2026-02-05 12:04:53 +01:00
BACKEND_ACE_STEP = ace-step| python| .| false| true
2026-03-09 17:29:32 +01:00
BACKEND_MLX_DISTRIBUTED = mlx-distributed| python| ./| false| true
2026-03-21 02:08:02 +01:00
BACKEND_TRL = trl| python| .| false| true
2026-03-22 00:56:34 +01:00
BACKEND_LLAMA_CPP_QUANTIZATION = llama-cpp-quantization| python| .| false| true
2026-01-04 21:12:50 +01:00
# Helper function to build docker image for a backend
# Usage: $(call docker-build-backend,BACKEND_NAME,DOCKERFILE_TYPE,BUILD_CONTEXT,PROGRESS_FLAG,NEEDS_BACKEND_ARG)
d e f i n e d o c k e r - b u i l d - b a c k e n d
d o c k e r b u i l d $( if $ ( filter -out false ,$ ( 4) ) ,$ ( 4) ) \
- - b u i l d - a r g BUILD_TYPE = $( BUILD_TYPE) \
--build-arg BASE_IMAGE = $( BASE_IMAGE) \
--build-arg CUDA_MAJOR_VERSION = $( CUDA_MAJOR_VERSION) \
--build-arg CUDA_MINOR_VERSION = $( CUDA_MINOR_VERSION) \
--build-arg UBUNTU_VERSION = $( UBUNTU_VERSION) \
2026-01-06 14:26:42 +00:00
--build-arg UBUNTU_CODENAME = $( UBUNTU_CODENAME) \
2026-01-04 21:12:50 +01:00
$( if $( filter true,$( 5) ) ,--build-arg BACKEND = $( 1) ) \
-t local-ai-backend:$( 1) -f backend/Dockerfile.$( 2) $( 3)
e n d e f
# Generate docker-build targets from backend definitions
d e f i n e g e n e r a t e - d o c k e r - b u i l d - t a r g e t
docker-build-$(word 1,$(subst |, ,$(1))) :
$$ ( call docker-build-backend,$( word 1,$( subst | , ,$( 1) ) ) ,$( word 2,$( subst | , ,$( 1) ) ) ,$( word 3,$( subst | , ,$( 1) ) ) ,$( word 4,$( subst | , ,$( 1) ) ) ,$( word 5,$( subst | , ,$( 1) ) ) )
e n d e f
# Generate all docker-build targets
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_LLAMA_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_HUGGINGFACE ) ) )
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_SILERO_VAD ) ) )
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_STABLEDIFFUSION_GGML ) ) )
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_WHISPER ) ) )
2026-02-09 09:12:05 +01:00
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_VOXTRAL ) ) )
2026-03-13 20:37:15 +00:00
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_OPUS ) ) )
2026-01-04 21:12:50 +01:00
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_RERANKERS ) ) )
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_TRANSFORMERS ) ) )
2026-02-03 21:57:50 +01:00
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_OUTETTS ) ) )
2026-01-04 21:12:50 +01:00
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_FASTER_WHISPER ) ) )
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_COQUI ) ) )
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_RFDETR ) ) )
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_KITTEN_TTS ) ) )
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_NEUTTS ) ) )
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_KOKORO ) ) )
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_VLLM ) ) )
2026-01-24 22:23:30 +01:00
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_VLLM_OMNI ) ) )
2026-01-04 21:12:50 +01:00
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_DIFFUSERS ) ) )
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_CHATTERBOX ) ) )
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_VIBEVOICE ) ) )
2026-01-07 21:44:35 +01:00
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_MOONSHINE ) ) )
2026-01-13 23:35:19 +01:00
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_POCKET_TTS ) ) )
2026-01-23 15:18:41 +01:00
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_QWEN_TTS ) ) )
2026-03-12 07:48:23 +01:00
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_FISH_SPEECH ) ) )
2026-02-27 08:16:51 +01:00
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_FASTER_QWEN 3_TTS ) ) )
2026-01-29 21:50:35 +01:00
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_QWEN_ASR ) ) )
2026-02-07 08:19:37 +01:00
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_NEMO ) ) )
2026-01-28 14:44:04 +01:00
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_VOXCPM ) ) )
feat(whisperx): add whisperx backend for transcription with speaker diarization (#8299)
* feat(proto): add speaker field to TranscriptSegment for diarization
Add speaker field to the gRPC TranscriptSegment message and map it
through the Go schema, enabling backends to return speaker labels.
Signed-off-by: eureka928 <meobius123@gmail.com>
* feat(whisperx): add whisperx backend for transcription with diarization
Add Python gRPC backend using WhisperX for speech-to-text with
word-level timestamps, forced alignment, and speaker diarization
via pyannote-audio when HF_TOKEN is provided.
Signed-off-by: eureka928 <meobius123@gmail.com>
* feat(whisperx): register whisperx backend in Makefile
Signed-off-by: eureka928 <meobius123@gmail.com>
* feat(whisperx): add whisperx meta and image entries to index.yaml
Signed-off-by: eureka928 <meobius123@gmail.com>
* ci(whisperx): add build matrix entries for CPU, CUDA 12/13, and ROCm
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(whisperx): unpin torch versions and use CPU index for cpu requirements
Address review feedback:
- Use --extra-index-url for CPU torch wheels to reduce size
- Remove torch version pins, let uv resolve compatible versions
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(whisperx): pin torch ROCm variant to fix CI build failure
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(whisperx): pin torch CPU variant to fix uv resolution failure
Pin torch==2.8.0+cpu so uv resolves the CPU wheel from the extra
index instead of picking torch==2.8.0+cu128 from PyPI, which pulls
unresolvable CUDA dependencies.
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(whisperx): use unsafe-best-match index strategy to fix uv resolution failure
uv's default first-match strategy finds torch on PyPI before checking
the extra index, causing it to pick torch==2.8.0+cu128 instead of the
CPU variant. This makes whisperx's transitive torch dependency
unresolvable. Using unsafe-best-match lets uv consider all indexes.
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(whisperx): drop +cpu local version suffix to fix uv resolution failure
PEP 440 ==2.8.0 matches 2.8.0+cpu from the extra index, avoiding the
issue where uv cannot locate an explicit +cpu local version specifier.
This aligns with the pattern used by all other CPU backends.
Signed-off-by: eureka928 <meobius123@gmail.com>
* fix(backends): drop +rocm local version suffixes from hipblas requirements to fix uv resolution
uv cannot resolve PEP 440 local version specifiers (e.g. +rocm6.4,
+rocm6.3) in pinned requirements. The --extra-index-url already points
to the correct ROCm wheel index and --index-strategy unsafe-best-match
(set in libbackend.sh) ensures the ROCm variant is preferred.
Applies the same fix as 7f5d72e8 (which resolved this for +cpu) across
all 14 hipblas requirements files.
Signed-off-by: eureka928 <meobius123@gmail.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: eureka928 <meobius123@gmail.com>
* revert: scope hipblas suffix fix to whisperx only
Reverts changes to non-whisperx hipblas requirements files per
maintainer review — other backends are building fine with the +rocm
local version suffix.
Signed-off-by: eureka928 <meobius123@gmail.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: eureka928 <meobius123@gmail.com>
---------
Signed-off-by: eureka928 <meobius123@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 10:33:12 -05:00
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_WHISPERX ) ) )
2026-02-05 12:04:53 +01:00
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_ACE_STEP ) ) )
2026-03-12 18:56:26 +01:00
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_ACESTEP_CPP ) ) )
2026-03-09 17:29:32 +01:00
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_MLX_DISTRIBUTED ) ) )
2026-03-21 02:08:02 +01:00
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_TRL ) ) )
2026-03-22 00:56:34 +01:00
$( eval $ ( call generate -docker -build -target ,$ ( BACKEND_LLAMA_CPP_QUANTIZATION ) ) )
2026-01-04 21:12:50 +01:00
# Pattern rule for docker-save targets
docker-save-% : backend -images
docker save local-ai-backend:$* -o backend-images/$* .tar
2025-07-18 13:24:12 +02:00
2026-03-22 00:56:34 +01:00
docker-build-backends : docker -build -llama -cpp docker -build -rerankers docker -build -vllm docker -build -vllm -omni docker -build -transformers docker -build -outetts docker -build -diffusers docker -build -kokoro docker -build -faster -whisper docker -build -coqui docker -build -chatterbox docker -build -vibevoice docker -build -moonshine docker -build -pocket -tts docker -build -qwen -tts docker -build -fish -speech docker -build -faster -qwen 3-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
2025-07-18 13:24:12 +02:00
2026-01-30 12:41:50 +01:00
########################################################
### Mock Backend for E2E Tests
########################################################
build-mock-backend : protogen -go
$( GOCMD) build -o tests/e2e/mock-backend/mock-backend ./tests/e2e/mock-backend
clean-mock-backend :
rm -f tests/e2e/mock-backend/mock-backend
2026-03-16 16:51:06 +00:00
########################################################
### UI E2E Test Server
########################################################
build-ui-test-server : build -mock -backend react -ui protogen -go
$( GOCMD) build -o tests/e2e-ui/ui-test-server ./tests/e2e-ui
test-ui-e2e : build -ui -test -server
cd core/http/react-ui && npm install && npx playwright install --with-deps chromium && npx playwright test
test-ui-e2e-docker :
docker build -t localai-ui-e2e -f tests/e2e-ui/Dockerfile .
docker run --rm localai-ui-e2e
clean-ui-test-server :
rm -f tests/e2e-ui/ui-test-server
2025-07-18 13:24:12 +02:00
########################################################
### END Backends
########################################################
2024-03-29 22:29:33 +01:00
.PHONY : swagger
swagger :
2024-04-21 01:19:57 +02:00
swag init -g core/http/app.go --output swagger
2024-05-19 18:24:27 +02:00
2026-03-05 21:47:12 +01:00
# DEPRECATED: gen-assets is for the legacy Alpine.js UI. Remove when legacy UI is removed.
2024-05-19 18:24:27 +02:00
.PHONY : gen -assets
gen-assets :
2025-01-30 00:03:01 +01:00
$( GOCMD) run core/dependencies_manager/manager.go webui_static.yaml core/http/static/assets
2024-06-13 00:47:16 +02:00
## Documentation
2024-07-05 19:19:38 +02:00
docs/layouts/_default :
2024-06-13 00:47:16 +02:00
mkdir -p docs/layouts/_default
docs/static/gallery.html : docs /layouts /_default
$( GOCMD) run ./.github/ci/modelslist.go ./gallery/index.yaml > docs/static/gallery.html
docs/public : docs /layouts /_default docs /static /gallery .html
cd docs && hugo --minify
docs-clean :
rm -rf docs/public
rm -rf docs/static/gallery.html
.PHONY : docs
docs : docs /static /gallery .html
2024-07-05 19:19:38 +02:00
cd docs && hugo serve
2025-08-26 14:22:04 +02:00
########################################################
## Platform-specific builds
########################################################
## fyne cross-platform build
build-launcher-darwin : build -launcher
go run github.com/tiagomelo/macos-dmg-creator/cmd/createdmg@latest \
--appName "LocalAI" \
--appBinaryPath " $( LAUNCHER_BINARY_NAME) " \
--bundleIdentifier "com.localai.launcher" \
--iconPath "core/http/static/logo.png" \
--outputDir "dist/"
build-launcher-linux :
2025-09-01 21:18:30 +01:00
cd cmd/launcher && go run fyne.io/tools/cmd/fyne@latest package -os linux -icon ../../core/http/static/logo.png --executable $( LAUNCHER_BINARY_NAME) -linux && mv launcher.tar.xz ../../$( LAUNCHER_BINARY_NAME) -linux.tar.xz