Skip to content

Add reusable native model package manager - #230

Open
mirek190 wants to merge 8 commits into
0xShug0:mainfrom
mirek190:local/native-model-manager-v2
Open

Add reusable native model package manager#230
mirek190 wants to merge 8 commits into
0xShug0:mainfrom
mirek190:local/native-model-manager-v2

Conversation

@mirek190

@mirek190 mirek190 commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Resolves #222

What changed

  • Added a reusable native C++ package-management library: audiocpp_package_manager.
  • Added the standalone audiocpp_model_manager executable for CLI, Docker, and headless workflows.
  • Updated audiocpp_server to call the same library directly while retaining its asynchronous HTTP job API for the native WebUI.
  • Kept tools/model_manager_v2.py available and supported during the migration.
  • Added native catalog inspection, download/install, progress, cancellation, partial cleanup, atomic publication, removal, inventory, and conservative remote-version checks.
  • Updated Windows, Linux Docker, and Nix packaging to include the standalone native manager.

Architecture

model_specs/*.json remains the editable source of truth. CMake embeds the active package catalog into the reusable library, while an explicitly supplied external catalog can still override it.

                         +-----------------------+
model_specs/*.json ----> | audiocpp_package_manager |
                         +-----------+-----------+
                                     |
                 +-------------------+-------------------+
                 |                                       |
                 v                                       v
      audiocpp_model_manager                    audiocpp_server
      CLI / Docker / headless              async HTTP API / WebUI

Python model_manager_v2.py remains available during migration.

The standalone executable exposes:

  • list [--remote]
  • info PACKAGE [--remote]
  • install PACKAGE [--overwrite]
  • clean PACKAGE
  • remove PACKAGE

list and info produce machine-readable JSON. The native executable is intentionally lightweight and does not link the inference runtime.

Validation

  • Native and Python catalogs both report 140 packages.
  • Full loader/catalog sync passed: 49 active loaders, 47 specs, 140 packages.
  • check_loader_catalog_sync.py --self-test passed.
  • Native list, single-package info, unknown-package failure, and portable execution without external specs passed.
  • Server installer lifecycle tests passed, including download, progress, cancellation, cleanup, shared sidecars, removal, and version-state coverage.
  • CUDA Release builds passed for both audiocpp_model_manager.exe and audiocpp_server.exe.
  • Windows package-script parsing passed.
  • git diff --check passed.

@mirek190
mirek190 marked this pull request as ready for review August 13, 2026 18:15
@0xShug0

0xShug0 commented Aug 13, 2026

Copy link
Copy Markdown
Owner

@mirek190 I don’t think we should remove the Python model_manager_v2.py or rewrite the docs around the assumption that the native UI/server is the only model-download path.

The native manager is a good addition, but the Python manager is still a useful alternative, especially for CLI, Docker, remote, and scripted/headless workflows. It feels odd to require users to start the UI or call server management endpoints just to download a model.

I’d prefer to keep model_manager_v2.py for now and present the native manager as an additional path used by the built-in UI. Long term, I think the C++ package management logic should live in a dedicated reusable library instead of being owned by the server. The server can expose it for the native UI, but CLI, Docker, remote, and scripted/headless users should not need to start audiocpp_server just to download models.

Once there is a native standalone manager with similar list / info / install / clean coverage, then removing the Python v2 manager would make much more sense.

@mirek190

mirek190 commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

So download manager should exist as a library available for server, cli and docker?

@0xShug0

0xShug0 commented Aug 13, 2026

Copy link
Copy Markdown
Owner

So download manager should exist as a library available for server, cli and docker?

For the C++-based manager, I mean making the core functionality a framework library so both the server and CLI can use it, while exposing an interface for model downloads (e.g., audiocpp_cli --download). But we don't need to do this now, as the non-UI user can just use the Python v2 manager in the repo.

@mirek190
mirek190 force-pushed the local/native-model-manager-v2 branch from ca0f282 to a98b9cb Compare August 14, 2026 00:16
@mirek190 mirek190 changed the title Replace Python model manager v2 with native server manager Add reusable native model package manager Aug 14, 2026
@mirek190

Copy link
Copy Markdown
Contributor Author

Updated this PR in response to the architecture feedback.

The Python v2 manager has been restored and remains supported. The native implementation is now additive and split into a reusable framework component rather than being owned by the server:

  • audiocpp_package_manager contains the embedded/external catalog handling, Hugging Face transfer logic, staging, progress, cleanup, atomic install, removal, inventory, and version-state logic.
  • audiocpp_model_manager provides a small standalone frontend for CLI, Docker, and headless use with list, info, install, clean, and remove commands.
  • audiocpp_server links the same library directly and remains the async HTTP/WebUI adapter; it does not launch or depend on the standalone executable.
  • CPU/CUDA Docker images, the Docker entrypoint, Nix packaging, and Windows portable packaging now include the standalone manager.

The dependency direction is therefore:

model_specs/*.json
        |
        v
audiocpp_package_manager
        |
        +--> audiocpp_model_manager  (CLI / Docker / headless)
        `--> audiocpp_server         (HTTP / native WebUI)

Validation completed locally:

  • native/Python catalog parity: 140 packages each
  • loader/catalog sync: 49 loaders, 47 specs, 140 packages
  • native manager portable smoke test without external specs
  • native list/info/error handling
  • server download/progress/cancel/clean/remove/version lifecycle tests
  • CUDA Release builds for the manager and server

The updated commit is a98b9cb.

@mirek190

Copy link
Copy Markdown
Contributor Author

Too late - already done. :)

As I had a fully working model manager I needed only few changes so that could works for server, cli, doker.
Also old py script still works.

@mirek190

Copy link
Copy Markdown
Contributor Author

Fixed the Nix failures in 9e500d7.

The failure was caused by the new native package-manager target calling find_package(CURL) while the Nix derivation did not expose libcurl headers or libraries. The derivation now includes curl in buildInputs.

I also corrected the install phase discovered while tracing this failure: it copied the native audiocpp_model_manager and then overwrote that executable with model_manager_v2.py. Nix now preserves both explicitly:

  • audiocpp_model_manager — native standalone executable
  • audiocpp_model_manager_v2.py — retained Python v2 manager during migration

Fresh CPU and Vulkan Nix checks are running now.

@0xShug0

0xShug0 commented Aug 14, 2026

Copy link
Copy Markdown
Owner

I can’t keep up 😂!

@mirek190

Copy link
Copy Markdown
Contributor Author

I can’t keep up 😂!

Are you working on MiniMax audio ?

I'm asking because I already have working importation and will be testing tomorrow.

@0xShug0

0xShug0 commented Aug 14, 2026

Copy link
Copy Markdown
Owner

@mirek190 Yes! End to end done and do some finetuning of code now

@mirek190

Copy link
Copy Markdown
Contributor Author

Cool 👍

@0xShug0

0xShug0 commented Aug 14, 2026

Copy link
Copy Markdown
Owner

@mirek190 Have you test your impl for longform (5min song) generation?

Update: the current blocker for me is longform can't do realtime.

@0xShug0

0xShug0 commented Aug 14, 2026

Copy link
Copy Markdown
Owner

I uploaded the GGUFs to HF and and push the code to branch preview/minimax-music-3.

Serveral unsolved issues: (1) longform performance (2) further memory optimizations for memory saver mode. (3) compoent quant combo and best layers to quant while preserving quality.

One challenge for me is to define the quality metrics. When bf16, if we force the the sampler output to match python, then python and cpp produce the high similar wav. After performance and memory optimizations like change precision, the song may change dramatically. It's still valid to me, but I just can't tell it's better or worse than the baseline.

Still need to more exepriments so the current code bypass spec v1 and the json entirely.

Feel free to change the code. I need to go back to PRs and issues...

@0xShug0

0xShug0 commented Aug 15, 2026

Copy link
Copy Markdown
Owner

@mirek190 The main blocker is that this PR introduces a mandatory external networking dependency, so audio.cpp is no longer self-contained for normal builds. In the init test, my local configure failed because the machine does not have the system libcurl dev headers/libraries installed. This is also likely to break the PR Docker builds: .devops/cpu.Dockerfile and .devops/cuda.Dockerfile now build audiocpp_model_manager, but their build stages do not install libcurl4-openssl-dev.

My preferred direction is closer to llama.cpp’s approach: use a small vendored HTTP client such as cpp-httplib, and keep model download support self-contained instead of requiring users to install libcurl dev packages. Moving to a self-contained HTTP backend is a larger design change, and I’m happy to take that on separately after releae 0.7.

After fixing the initial build blocker, quick validation suggests that both audiocpp_model_manager and the server download path work correctly.

@mirek190

Copy link
Copy Markdown
Contributor Author

@mirek190 The main blocker is that this PR introduces a mandatory external networking dependency, so audio.cpp is no longer self-contained for normal builds. In the init test, my local configure failed because the machine does not have the system libcurl dev headers/libraries installed. This is also likely to break the PR Docker builds: .devops/cpu.Dockerfile and .devops/cuda.Dockerfile now build audiocpp_model_manager, but their build stages do not install libcurl4-openssl-dev.

My preferred direction is closer to llama.cpp’s approach: use a small vendored HTTP client such as cpp-httplib, and keep model download support self-contained instead of requiring users to install libcurl dev packages. Moving to a self-contained HTTP backend is a larger design change, and I’m happy to take that on separately after releae 0.7.

After fixing the initial build blocker, quick validation suggests that both audiocpp_model_manager and the server download path work correctly.

You actually right. We need something more universal.
We are use cpp-httplib with bundled TLS backend BoringSSL

@mirek190
mirek190 force-pushed the local/native-model-manager-v2 branch from 9e500d7 to 0c6bae3 Compare August 16, 2026 00:08
@mirek190

Copy link
Copy Markdown
Contributor Author

Updated the networking layer and synchronized this PR with current main (502b5b7).

The native package manager no longer has separate WinHTTP and libcurl implementations. It now follows the llama.cpp-style self-contained arrangement:

  • vendored split cpp-httplib provides one HTTP implementation on Windows, Linux, and macOS
  • pinned BoringSSL 0.20260813.0 provides HTTPS and is linked statically by default
  • no system libcurl development package, system OpenSSL development package, or separate TLS runtime DLL is required
  • Hugging Face authentication, redirects, streamed writes, progress callbacks, cancellation, staging cleanup, and atomic publication remain supported
  • packagers may explicitly use system OpenSSL with AUDIOCPP_BUILD_BORINGSSL=OFF and AUDIOCPP_USE_SYSTEM_OPENSSL=ON

For reproducible/sandboxed builds, CMake also accepts AUDIOCPP_BORINGSSL_ARCHIVE. The Nix derivation supplies the pinned archive as a fixed-output input, so CMake performs no network access inside the Nix sandbox. Docker build stages retain only CA certificates for the default verified source fetch; the temporary libcurl development dependency was removed from Nix and Linux CI.

The first post-update Nix run exposed one packaging-specific issue: Nix injects a global -Werror, which was inherited by BoringSSL and promoted its intentionally unused compatibility parameters to build errors. Commit 5b7dd49 now disables warning-as-error only for the bundled crypto, ssl, and fipsmodule targets. audio.cpp's own warning policy is unchanged.

Validation completed after rebasing:

  • CUDA Release audiocpp_model_manager build
  • CUDA Release audiocpp_server build
  • fresh CPU manager build from a pre-fetched/offline BoringSSL archive
  • real Hugging Face HTTPS metadata lookup
  • server installer progress/cancel/cleanup test suite
  • native server model-management endpoint smoke test
  • Windows dependency inspection: no curl/OpenSSL/BoringSSL DLL dependency
  • forced-warning BoringSSL build check confirming the third-party targets override parent warning-as-error flags

Current head: 5b7dd49.

@mirek190

Copy link
Copy Markdown
Contributor Author

Follow-up on the Nix CI correction:

The initial Nix failures were not caused by the native package-manager transport itself. audio.cpp enables strict warning flags globally (-Werror and -pedantic-errors), and those flags leaked into the pinned BoringSSL build. BoringSSL intentionally uses GNU vector compound literals and has harmless unused parameters in non-FIPS paths, so GCC 15 rejected the third-party sources.

The first correction covered the main crypto, ssl, and fipsmodule targets. The later Nix failure showed that an all-target Nix build also compiles BoringSSL's auxiliary decrepit library. The final fix therefore discovers every target under the fetched BoringSSL source tree recursively and disables warning-as-error/pedantic enforcement only for those third-party targets. audio.cpp's own strict warning policy remains unchanged.

Final verification on 6d030ba:

  • Nix CPU: pass (14m42s)
  • Nix Vulkan: pass (10m46s)
  • Linux CPU: pass (11m59s)
  • Linux Vulkan: pass (15m13s)
  • Windows CPU: pass (12m51s)
  • macOS CPU: pass (6m43s)

This keeps the bundled cpp-httplib + static BoringSSL transport, avoids a libcurl/system-OpenSSL development dependency, and is now clean across the full PR build matrix.

@0xShug0

0xShug0 commented Aug 16, 2026

Copy link
Copy Markdown
Owner

@mirek190 Lightning speed ⚡ !

Could you scope the build and dependency? My original plan (which I didn’t get a chance to implement 😄), was:

Build native HTTP/TLS dependency: Default OFF
Build audiocpp_model_manager: Default OFF
audiocpp_cli: Do not pull native HTTP/TLS dependency.
audiocpp_model_manager: Pull native HTTP/TLS dependency.
audiocpp_server without native install/download support compiled in: Not pull
audiocpp_server with native UI install/download support compiled in: Pull native HTTP/TLS dependency.

Basically, only pull and build the dependency when the user intends to use it.

I think we only need one flag controlling whether to build audiocpp_model_manager: AUDIOCPP_BUILD_NATIVE_MODEL_MANAGER.
Inside that build block, we can keep a second optional packager override flag: AUDIOCPP_USE_SYSTEM_OPENSSL.
Both should default to OFF.

Different cases:

Server/cli only. No downloads. No build cmd change.

cmake -S . -B build/debug -DCMAKE_BUILD_TYPE=Debug
cmake --build build/debug --target audiocpp_cli audiocpp_server -j

Server + UI + config mode. No download.

cmake -S . -B build/debug -DCMAKE_BUILD_TYPE=Debug
cmake --build build/debug --target audiocpp_server -j
build/debug/bin/audiocpp_server --config server.json --ui

Server + normal UI. Need download by default

cmake -S . -B build/debug \
  -DCMAKE_BUILD_TYPE=Debug \
  -DAUDIOCPP_BUILD_NATIVE_MODEL_MANAGER=ON

cmake --build build/debug --target audiocpp_server -j
build/debug/bin/audiocpp_server --ui --ui-management

Manager alone

cmake -S . -B build/debug \
  -DCMAKE_BUILD_TYPE=Debug \
  -DAUDIOCPP_BUILD_NATIVE_MODEL_MANAGER=ON

cmake --build build/debug --target audiocpp_model_manager -j

Then for packager wants system OpenSSL instead of bundled BoringSSL

cmake -S . -B build/debug \
  -DCMAKE_BUILD_TYPE=Debug \
  -DAUDIOCPP_BUILD_NATIVE_MODEL_MANAGER=ON \
  -DAUDIOCPP_USE_SYSTEM_OPENSSL=ON

cmake --build build/debug --target audiocpp_model_manager -j

@mirek190

Copy link
Copy Markdown
Contributor Author

OK we can change it to more modular

  • AUDIOCPP_BUILD_NATIVE_MODEL_MANAGER=OFF by default.

  • Normal CLI/server builds contain no HTTP/TLS download dependency.

    • audiocpp_model_manager
    • server download/install support
    • bundled BoringSSL by default
  • AUDIOCPP_USE_SYSTEM_OPENSSL=ON replaces bundled BoringSSL when management is enabled.

  • Remove AUDIOCPP_BUILD_BORINGSSL; it becomes unnecessary.

  • If a server built without management receives --ui-management, it should show a clear startup error explaining which
    CMake flag is required.

  • Docker/Nix packages that include downloads should explicitly enable the flag.

  • Add a dedicated CI build with management enabled, since ordinary builds would no longer compile that code.

The server should conditionally include model_installer.cpp, link audiocpp_package_manager, and expose management
endpoints only when the feature was compiled in.

Keep normal CLI and server builds free of HTTP and TLS dependencies. Build the reusable package manager, standalone manager executable, managed WebUI endpoints, and bundled BoringSSL only when AUDIOCPP_BUILD_NATIVE_MODEL_MANAGER is enabled. Allow packagers to select system OpenSSL explicitly, and make Docker and Nix opt into the managed configuration.
@mirek190

Copy link
Copy Markdown
Contributor Author

Implemented the opt-in architecture requested in commit 8eadb4c.

Configuration / launch Result
Default build audiocpp_cli and audiocpp_server do not configure or link cpp-httplib, BoringSSL, or OpenSSL. The standalone manager target is absent.
Default build + --ui The embedded UI and ordinary configured inference remain available without HTTP/TLS download support.
Default build + --ui-management Exits with a clear instruction to rebuild with AUDIOCPP_BUILD_NATIVE_MODEL_MANAGER=ON.
AUDIOCPP_BUILD_NATIVE_MODEL_MANAGER=ON Builds audiocpp_package_manager and audiocpp_model_manager, enables the server install/download routes, and uses bundled pinned BoringSSL by default. Run the managed UI with audiocpp_server --ui --ui-management.
Manager ON + AUDIOCPP_USE_SYSTEM_OPENSSL=ON Uses the packager-provided OpenSSL installation instead of bundled BoringSSL.
Docker / Nix Packaging explicitly opts into the manager. The Nix package exposes nativeModelManagerSupport so downstream packages can disable it.

Additional Windows portability fixes replace CreateFile2 with the equivalent CreateFileW mapping path and define the supported Windows API target for MinGW.

Validation completed:

  • Feature OFF: configured and built audiocpp_cli and audiocpp_server; verified the package-manager/TLS and standalone-manager targets were absent.
  • Feature OFF runtime: --ui --ui-management was rejected with the expected rebuild instruction.
  • Feature ON: configured and built audiocpp_model_manager, audiocpp_server, and server_model_installer_test using bundled BoringSSL.
  • server_model_installer_test: passed 1/1.
  • Standalone manager: embedded catalog list command returned valid package JSON.
  • Windows CUDA Release: audiocpp_server.exe and audiocpp_model_manager.exe rebuilt successfully with native management enabled.

This leaves the downloader as a reusable opt-in library for the server and standalone manager while keeping normal CLI/server inference builds dependency-free.

Avoid compiling bundled BoringSSL concurrently with Vulkan shader generation in Nix builds. Use the Nix-provided OpenSSL package through the native manager's explicit system TLS override while retaining bundled BoringSSL for portable non-Nix builds.
@mirek190

Copy link
Copy Markdown
Contributor Author

Follow-up fix pushed in 61a00e7 for the failed Nix Vulkan check.

The failure was a late Vulkan link error for missing generated subgroup-matmul shader symbols. Enabling the native manager made Nix compile bundled BoringSSL concurrently with ggml's internally parallel Vulkan shader generation; individual glslc failures are swallowed by the upstream generator, so the visible symptom was an incomplete shader source and undefined references at link time.

Nix now uses its packaged OpenSSL through AUDIOCPP_USE_SYSTEM_OPENSSL=ON instead of building bundled BoringSSL. Native manager HTTPS remains enabled, while the Nix build avoids the extra compiler workload and uses the normal reproducible Nix TLS dependency. Portable Docker and ordinary opt-in builds continue to use bundled BoringSSL by default.

The Nix expression passes diff/syntax structure checks locally; a local Nix installation is not available on this Windows host, so the newly triggered CPU/Vulkan Nix jobs are the authoritative build verification.

@0xShug0

0xShug0 commented Aug 16, 2026

Copy link
Copy Markdown
Owner

Thanks! I wil test it tomorrow.

@mirek190

Copy link
Copy Markdown
Contributor Author

Thanks! I wil test it tomorrow.

sure ... no problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature request] Move model management out of python into .cpp + hf cli

2 participants