Skip to content

QVAC-23295 fix[api]: address CosyVoice3 post-merge review comments - #3737

Merged
mexxik merged 8 commits into
mainfrom
fix/QVAC-23295-cosyvoice-review-followups
Aug 11, 2026
Merged

QVAC-23295 fix[api]: address CosyVoice3 post-merge review comments#3737
mexxik merged 8 commits into
mainfrom
fix/QVAC-23295-cosyvoice-review-followups

Conversation

@mexxik

@mexxik mexxik commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Follow-up on the merged CosyVoice3 engine (#3446), addressing the four post-merge
review comments in @qvac/tts-ggml.

# Comment Fix
1 openclCacheDir sent by JS but dropped at the C++ boundary Added CosyvoiceConfig::openclCacheDir → read in buildCosyvoiceConfig → forwarded to EngineOptions::opencl_cache_dir in toEngineOptions. Without it the Android OpenCL/Adreno GPU path recompiled kernels every process.
2 streamLeftContextTokens documented as effective Marked reserved / not yet effective (the pinned engine accepts but never reads it) in the TS surface, index.d.ts, and CosyvoiceConfig.hpp, mirroring cfmSteps.
3 instruct accepted malformed values { dialect: '' }, { dialect: null }, arrays, and non-objects silently degraded to zero-shot. Now rejected: non-object/array values throw, and controls are validated by property presence rather than truthiness.
4 Stale "CPU-only (ignored)" GPU contract The pinned engine honors n_gpu_layers > 0 on the OpenCL/Adreno path and the addon forwards useGPU/nGpuLayers. Updated CosyvoiceConfig docs + README (CPU-only claims), and added GPU-forwarding tests.

Also resolves stray merge-conflict markers left in CHANGELOG.md by an earlier merge.

Testing

  • toEngineOptions exposed as a free function so the OpenCL cache-dir and GPU
    intent forwarding are unit-tested without model weights
    (addon/tests/test_cosyvoice_config.cpp).
  • JS: test/unit/cosyvoice3.inference.test.js — instruct regression cases for
    empty/null/array/number and the undefined-skip precedence path. 20/20 pass;
    88/88 across the other mocked engine suites.
  • index.js / index.d.ts regenerated from src/index.ts; eslint / prettier /
    lunte / clang-format / clang-tidy clean.

No version bump here (kept for a separate release PR per convention).

@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

License compliance — clean

No new dependency license findings in this PR.

Warn-only (shadow) mode — this check does not block merges yet.

Updated automatically by the canonical license compliance workflow.

NOTICE presence (advisory)

Missing NOTICE (advisory, does not block):

  • ./.github/actions/release-merge-guard
  • ./packages/vla-ggml/sim/server
  • ./packages/asr-ggml/benchmarks/server
  • ./packages/embed-llamacpp/benchmarks/performance
  • ./packages/embed-llamacpp/benchmarks/server
  • ./packages/llm-llamacpp/benchmarks/performance
  • ./packages/llm-llamacpp/benchmarks/server
  • ./packages/inference-addon-cpp/mobile
  • ./packages/ggml-coload-smoke
  • ./packages/sdk/e2e
  • ./packages/fabric/test/integration
  • ./docs/website

@mexxik
mexxik marked this pull request as ready for review August 10, 2026 09:10
@mexxik
mexxik requested review from a team as code owners August 10, 2026 09:10
@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Status

Current Status: ✅ APPROVED
Approvals so far: Team Lead: 1, Member: 1

@mexxik mexxik added the tier1 label Aug 10, 2026
Follow-up on the merged CosyVoice3 engine (#3446), addressing four review
comments in @qvac/tts-ggml:

- Forward openclCacheDir to the native engine. The JS layer sent it but the
  addon dropped it, so CosyVoice3's Android OpenCL/Adreno GPU path recompiled
  its kernels every process instead of reusing the persistent cache. Add
  CosyvoiceConfig::openclCacheDir, read it in buildCosyvoiceConfig, and forward
  it to EngineOptions::opencl_cache_dir. Expose toEngineOptions as a free
  function so the GPU/OpenCL forwarding is unit-tested without weights.

- Mark streamLeftContextTokens reserved / not yet effective. The pinned tts-cpp
  engine accepts but does not read it, so setting it has no effect; document it
  like cfmSteps in both the TS surface and CosyvoiceConfig.

- Harden instruct validation. A set-but-empty or null control ({ dialect: '' },
  { dialect: null }), an array, or a non-object silently degraded to zero-shot
  synthesis. Reject non-object/array values and validate controls by property
  presence rather than truthiness, with regression coverage.

- Fix the stale CPU-only contract. The pinned engine now runs CosyVoice3 on the
  OpenCL/Adreno GPU path when nGpuLayers/useGpu request it, and the addon
  forwards that intent. Update CosyvoiceConfig and the README accordingly, and
  add GPU-forwarding tests. Also resolve stray merge-conflict markers left in
  the CHANGELOG.
@mexxik
mexxik force-pushed the fix/QVAC-23295-cosyvoice-review-followups branch from 1fe2e2a to 1da1bb8 Compare August 10, 2026 09:23

@GustavoA1604 GustavoA1604 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[medium] packages/tts-ggml/src/index.ts — line 149 (if (instruct == null) return "";)

An explicit instruct: null still silently selects zero-shot synthesis, contradicting the new validation contract. Treat only undefined as omitted, reject null, add a regression test, and regenerate index.js.

[low] packages/tts-ggml/src/index.ts — line 155 (typeof instruct !== "object" || Array.isArray(instruct))

This does not enforce the stated plain-object requirement: new Date() silently becomes zero-shot, while inherited controls can be accepted. Require an ordinary object with own control properties and test these cases.

[medium] packages/tts-ggml/addon/src/js-interface/JSAdapter.cpp — line 286 (cfg.openclCacheDir =)

The native test constructs CosyvoiceConfig directly, so it cannot catch the original JS-boundary regression. Add coverage proving a JavaScript openclCacheDir passes through buildCosyvoiceConfig into EngineOptions::opencl_cache_dir.

[medium] packages/tts-ggml/README.md — line 560 (streamLeftContextTokens)

This table still describes the option as effective for CosyVoice3 and Chatterbox, contradicting the updated declaration and nearby documentation. Mark it CosyVoice3-only and reserved/not yet effective.

[low] README.md — line 41 (Text-to-Speech)

The repository documentation rule requires both README levels to reflect changed public functionality. Update the root TTS entry to mention CosyVoice3’s opt-in Android OpenCL/Adreno offload.

Second review round on the CosyVoice3 follow-ups:

- Reject an explicit `instruct: null`. Only `undefined` counts as omitted
  (zero-shot); `null` is now treated as a malformed value like any other
  non-object.

- Require a plain control object. A `Date`, class instance, or other exotic
  object previously slipped past the object check and degraded to zero-shot,
  and controls could be picked up from an inherited prototype. Validate the
  value defensively (own-property, ordinary object) so only own control keys
  of a plain object are honored.

- Cover the openclCacheDir JS boundary. Add a unit test proving the JS layer
  emits `openclCacheDir` into the native configuration params (the key the
  addon's buildCosyvoiceConfig reads), from both the option and config; the
  config -> EngineOptions::opencl_cache_dir half stays covered by
  test_cosyvoice_config.cpp.

- README: mark `streamLeftContextTokens` CosyVoice3-only and reserved / not yet
  effective in the options table, and note CosyVoice3's opt-in Android
  OpenCL/Adreno GPU offload in the root package overview.
GustavoA1604
GustavoA1604 previously approved these changes Aug 10, 2026
pratiknarola-t
pratiknarola-t previously approved these changes Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tier1 verified Retired - no longer authorizes CI. Fork PRs use fork-ci environment approval. verify

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants