common: support the DSpark sidecar resolution (#26458)

The dspark- files resolve like the other speculative sidecars: the
-hfd tag applies to them, a requested sidecar resolves without a full
model at the tag, and an explicit -md selection disables the discovery.
When no type is requested, dspark outranks dflash in the auto-selection
since its sidecar carries the extra Markov head.
This commit is contained in:
Pascal
2026-08-02 19:25:27 +02:00
committed by GitHub
parent 3581ba0cf5
commit bb4e0e1b3f
3 changed files with 52 additions and 5 deletions

View File

@@ -374,6 +374,10 @@ common_models_handler common_models_handler_init(const common_params & params, l
params.speculative.types.end(),
COMMON_SPECULATIVE_TYPE_DRAFT_EAGLE3) != params.speculative.types.end();
const bool spec_type_draft_dspark = std::find(params.speculative.types.begin(),
params.speculative.types.end(),
COMMON_SPECULATIVE_TYPE_DRAFT_DSPARK) != params.speculative.types.end();
// only download mmproj if the current example is using it
bool use_mmproj = false;
for (const auto & ex : mmproj_examples) {
@@ -388,6 +392,7 @@ common_models_handler common_models_handler_init(const common_params & params, l
opts.download_mtp = spec_type_draft_mtp;
opts.download_eagle3 = spec_type_draft_eagle3;
opts.download_dflash = spec_type_draft_dflash;
opts.download_dspark = spec_type_draft_dspark;
opts.download_mmproj = use_mmproj && !params.no_mmproj
&& params.mmproj.path.empty() && params.mmproj.url.empty();
@@ -402,6 +407,7 @@ common_models_handler common_models_handler_init(const common_params & params, l
opts_spec.download_mtp = true;
opts_spec.download_dflash = true;
opts_spec.download_eagle3 = true;
opts_spec.download_dspark = true;
}
plan_spec = common_download_get_hf_plan(params.speculative.draft.mparams, opts_spec);
}
@@ -544,12 +550,19 @@ void common_models_handler_apply(common_models_handler & handler, common_params
plan_spec.mtp = {};
plan_spec.dflash = {};
plan_spec.eagle3 = {};
plan_spec.dspark = {};
}
// infer the speculative type from the sidecar shipped by the draft repo when none is requested
if (spec_types_is_default(params)) {
if (!plan_spec.mtp.local_path.empty()) {
params.speculative.types = { COMMON_SPECULATIVE_TYPE_DRAFT_MTP };
plan_spec.dspark = {};
plan_spec.dflash = {};
plan_spec.eagle3 = {};
} else if (!plan_spec.dspark.local_path.empty()) {
// dspark outranks dflash, its sidecar carries the extra Markov head
params.speculative.types = { COMMON_SPECULATIVE_TYPE_DRAFT_DSPARK };
plan_spec.dflash = {};
plan_spec.eagle3 = {};
} else if (!plan_spec.dflash.local_path.empty()) {
@@ -563,7 +576,8 @@ void common_models_handler_apply(common_models_handler & handler, common_params
// when a sidecar type is requested, the draft repo resolves to its sidecar instead of a full model
const bool spec_sidecar_found = !plan_spec.mtp.local_path.empty() ||
!plan_spec.dflash.local_path.empty() ||
!plan_spec.eagle3.local_path.empty();
!plan_spec.eagle3.local_path.empty() ||
!plan_spec.dspark.local_path.empty();
if (!plan_spec.mtp.local_path.empty() && !had_spec_url) {
tasks.emplace_back(plan_spec.mtp, opts, [&]() {
// only use the discovered MTP head when no draft path is set yet
@@ -594,6 +608,16 @@ void common_models_handler_apply(common_models_handler & handler, common_params
}
});
}
if (!plan_spec.dspark.local_path.empty() && !had_spec_url) {
tasks.emplace_back(plan_spec.dspark, opts, [&]() {
// only use the discovered DSpark sidecar when no draft path is set yet
if (params.speculative.draft.mparams.path.empty()) {
params.speculative.draft.mparams.path = hf_cache::finalize_file(plan_spec.dspark);
} else {
hf_cache::finalize_file(plan_spec.dspark);
}
});
}
// a wired draft sidecar counts as an explicit draft for the main plan fallback below
if (spec_sidecar_found) {
@@ -649,6 +673,16 @@ void common_models_handler_apply(common_models_handler & handler, common_params
}
});
}
if (!plan.dspark.local_path.empty() && !had_spec_url) {
tasks.emplace_back(plan.dspark, opts, [&]() {
// only fall back to the discovered DSpark sidecar when no draft was explicitly provided
if (params.speculative.draft.mparams.empty()) {
params.speculative.draft.mparams.path = hf_cache::finalize_file(plan.dspark);
} else {
hf_cache::finalize_file(plan.dspark);
}
});
}
if (!plan.preset.local_path.empty()) {
tasks.emplace_back(plan.preset, opts, [&]() {
// if HF repo is a preset repo, we simply run server in router mode with the preset.ini file