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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2389,6 +2389,19 @@ if (ENGINE_BUILD_TESTS)
NAME server_model_installer_test
COMMAND server_model_installer_test
)

add_executable(package_manager_modelscope_test
tests/unittests/test_package_manager_modelscope.cpp
)
target_link_libraries(package_manager_modelscope_test PRIVATE
Threads::Threads audiocpp_package_manager)
target_compile_definitions(package_manager_modelscope_test PRIVATE
AUDIOCPP_NATIVE_MANAGER_FIXTURE="${CMAKE_CURRENT_SOURCE_DIR}/tests/fixtures/native_model_manager_server.py")

add_test(
NAME package_manager_modelscope_test
COMMAND package_manager_modelscope_test
)
endif()

if (ENGINE_BUILD_MODEL_TESTS)
Expand Down
9 changes: 9 additions & 0 deletions docs/maintainers/model_specs.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,15 @@ overrides.
}
```

`kind: "modelscope_snapshot"` downloads the same way from a ModelScope
(modelscope.cn) repo. It takes the same fields (`repo` required, `revision`
optional); the only differences are that the default revision is `master`
(ModelScope's default branch) and the `gated` flag does not apply. The native
package manager resolves the endpoint through `AUDIOCPP_MS_BASE_URL`
(default `https://www.modelscope.cn`), mirroring `AUDIOCPP_HF_BASE_URL` for
Hugging Face. ModelScope requests authenticate with `AUDIOCPP_MS_TOKEN` only;
the Hugging Face token is never sent to a ModelScope endpoint.

Dependencies describe extra model-level resources required by runtime features.
Use `kind: "model"` for another model family, and `kind: "bundled_model"` for an
in-repo bundled model asset. Do not use dependencies for sidecars or tensor
Expand Down
38 changes: 38 additions & 0 deletions docs/model_manager.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,44 @@ For support status and tested precision coverage, see the [GGUF guide](gguf.md).
For measured 16-bit vs Q8 speed and peak-VRAM results, see the
[Q8 performance report](reports/gguf_q8_performance.md).

## Download Sources

Both the native package manager and `tools/model_manager_v2.py` download from
Hugging Face (`kind: "huggingface_snapshot"`) or ModelScope
(`kind: "modelscope_snapshot"`); see
[maintainers/model_specs.md](maintainers/model_specs.md) for the spec fields.
The native endpoints can be overridden for mirrors or tests with
`AUDIOCPP_HF_BASE_URL` (default `https://huggingface.co`) and
`AUDIOCPP_MS_BASE_URL` (default `https://www.modelscope.cn`). The Python tool
uses the standard `HF_ENDPOINT` for Hugging Face and the same
`AUDIOCPP_MS_BASE_URL` for ModelScope.

Authentication is provider-scoped: Hugging Face requests may carry
`HF_TOKEN` / `HUGGING_FACE_HUB_TOKEN`, while ModelScope requests only carry
`AUDIOCPP_MS_TOKEN` (optional, for access-restricted ModelScope repos). The
Hugging Face token is never sent to a ModelScope endpoint, and vice versa.

### Python Source Override

The Python v2 manager can redirect any package to ModelScope on demand,
without editing `model_specs/*.json`:

```bash
python3 tools/model_manager_v2.py install qwen3_tts --source modelscope --source-repo HereIsMark/audio.cpp-gguf
```

`--source modelscope` is accepted by `install` and `sizes`. `--source-repo`
names the ModelScope repo (`namespace/name`); when omitted, the spec's own
repo name is reused on ModelScope. Passing `--source-repo` without
`--source modelscope` is rejected. Revision translation: a spec revision that
is unset or `main` becomes ModelScope's default branch `master`; any other
explicit revision passes through unchanged.

Note that manifest etags are source-specific (Hugging Face etag vs ModelScope
sha256), so cross-source freshness checks can spuriously report that an
installed package has an update. Query with the same `--source` that was used
to install.

## Dependencies

The native manager needs no Python runtime. The default bundled-TLS build needs
Expand Down
8 changes: 4 additions & 4 deletions src/framework/model_spec/schema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ const std::unordered_set<std::string> & precisions() {

const std::unordered_set<std::string> & download_kinds() {
static const std::unordered_set<std::string> values = {
"huggingface_snapshot", "local_snapshot", "converter", "unsupported",
"huggingface_snapshot", "modelscope_snapshot", "local_snapshot", "converter", "unsupported",
};
return values;
}
Expand Down Expand Up @@ -408,7 +408,7 @@ void validate_runtime(const json::Value & value, std::string_view path) {
validate_string_array(require_spec_field(value, "tags", path), &runtime_tags(), std::string(path) + ".tags", "runtime tag");
}

void validate_hf_snapshot_download(const json::Value & value, std::string_view path) {
void validate_snapshot_download(const json::Value & value, std::string_view path) {
require_spec_object(value, path);
(void) require_spec_string(require_spec_field(value, "repo", path), std::string(path) + ".repo");
if (const auto * revision = value.find("revision")) {
Expand All @@ -431,8 +431,8 @@ void validate_download(const json::Value & value, std::string_view path) {
require_spec_object(value, path);
const auto kind = require_spec_string(require_spec_field(value, "kind", path), std::string(path) + ".kind");
validate_enum(kind, download_kinds(), std::string(path) + ".kind", "download kind");
if (kind == "huggingface_snapshot") {
validate_hf_snapshot_download(value, path);
if (kind == "huggingface_snapshot" || kind == "modelscope_snapshot") {
validate_snapshot_download(value, path);
} else if (kind == "local_snapshot") {
(void) require_spec_string(require_spec_field(value, "path", path), std::string(path) + ".path");
if (const auto * array = value.find("include")) {
Expand Down
Loading
Loading