Skip to content

Remove cppinyin from zipvoice - #2892

Merged
csukuangfj merged 2 commits into
k2-fsa:masterfrom
csukuangfj:refactor-zipvoice-cpp
Dec 11, 2025
Merged

csukuangfj merged 2 commits into
k2-fsa:masterfrom
csukuangfj:refactor-zipvoice-cpp

Conversation

@csukuangfj

@csukuangfj csukuangfj commented Dec 11, 2025 •

Copy link
Copy Markdown
Collaborator

For the following test,

Beofre this PR With this PR
RTF 0.793 0.799
./sherpa-onnx-v1.12.19-osx-universal2-shared/bin/sherpa-onnx-offline-zeroshot-tts \
  --zipvoice-flow-matching-model=sherpa-onnx-zipvoice-distill-zh-en-emilia/fm_decoder_int8.onnx \
  --zipvoice-text-model=sherpa-onnx-zipvoice-distill-zh-en-emilia/text_encoder_int8.onnx \
  --zipvoice-data-dir=sherpa-onnx-zipvoice-distill-zh-en-emilia/espeak-ng-data \
  --zipvoice-pinyin-dict=sherpa-onnx-zipvoice-distill-zh-en-emilia/pinyin.raw \
  --zipvoice-tokens=sherpa-onnx-zipvoice-distill-zh-en-emilia/tokens.txt \
  --zipvoice-vocoder=sherpa-onnx-zipvoice-distill-zh-en-emilia/vocos_24khz.onnx \
  --prompt-audio=sherpa-onnx-zipvoice-distill-zh-en-emilia/prompt.wav \
  --num-steps=4 \
  --num-threads=1 \
  --prompt-text="周日被我射熄火了,所以今天是周一。" \
  "我是中国人民的儿子,我爱我的祖国。我得祖国是一个伟大的国家,拥有五千年的文明史。"

./sherpa-onnx-v1.12.20-osx-universal2-shared/bin/sherpa-onnx-offline-zeroshot-tts \
  --zipvoice-encoder=sherpa-onnx-zipvoice-distill-int8-zh-en-emilia/encoder.int8.onnx \
  --zipvoice-decoder=sherpa-onnx-zipvoice-distill-int8-zh-en-emilia/decoder.int8.onnx \
  --zipvoice-data-dir=sherpa-onnx-zipvoice-distill-int8-zh-en-emilia/espeak-ng-data \
  --zipvoice-lexicon=sherpa-onnx-zipvoice-distill-int8-zh-en-emilia/lexicon.txt \
  --zipvoice-tokens=sherpa-onnx-zipvoice-distill-int8-zh-en-emilia/tokens.txt \
  --zipvoice-vocoder=sherpa-onnx-zipvoice-distill-zh-en-emilia/vocos_24khz.onnx \
  --prompt-audio=sherpa-onnx-zipvoice-distill-zh-en-emilia/prompt.wav \
  --num-steps=4 \
  --num-threads=1 \
  --prompt-text="周日被我射熄火了,所以今天是周一。" \
  --output-filename=./new.wav \
  "我是中国人民的儿子,我爱我的祖国。我得祖国是一个伟大的国家,拥有五千年的文明史。"
Screenshot 2025-12-18 at 14 56 06 Screenshot 2025-12-18 at 14 49 56

@dosubot dosubot Bot added the size:XL This PR changes 500-999 lines, ignoring generated files. label Dec 11, 2025
@coderabbitai

coderabbitai Bot commented Dec 11, 2025 •

Copy link
Copy Markdown

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

This PR removes cppinyin and the OfflineTtsZipvoiceFrontend, migrates TTS tokenization to MatchaTtsLexicon, adds a lexicon field to ZipVoice model config, and updates build/linking scripts to stop including cppinyin.

Changes

Cohort / File(s) Summary
Build system & cppinyin removal
CMakeLists.txt, cmake/cppinyin.cmake, cmake/cppinyin.patch, cmake/sherpa-onnx-static.pc.in, build-ios.sh, build-swift-macos.sh
Removed cppinyin FetchContent and build integration, deleted cppinyin patch/CMake helper, removed -lcppinyin_core from pkg-config template, and excluded libcppinyin_core.a from iOS/macOS static bundles.
Platform/example linker updates
c-api-examples/Makefile, mfc-examples/NonStreamingSpeechRecognition/sherpa-onnx-deps.props, mfc-examples/NonStreamingTextToSpeech/sherpa-onnx-deps.props, mfc-examples/StreamingSpeechRecognition/sherpa-onnx-deps.props, sherpa-onnx/pascal-api/sherpa_onnx.pas
Removed cppinyin_core linkage from example and platform dependency manifests; added ONNX Runtime rpath in c-api-examples/Makefile.
TTS build & sources
sherpa-onnx/csrc/CMakeLists.txt
Removed offline-tts-zipvoice-frontend.cc from TTS sources and removed cppinyin_core from target_link_libraries for TTS.
ZipVoice frontend removed
sherpa-onnx/csrc/offline-tts-zipvoice-frontend.h, sherpa-onnx/csrc/offline-tts-zipvoice-frontend.cc, sherpa-onnx/csrc/offline-tts-zipvoice-frontend-test.cc
Deleted the OfflineTtsZipvoiceFrontend header, implementation, and its test — removing pinyin/espeak-ng based tokenization logic and public API for that frontend.
MatchaTtsLexicon API change
sherpa-onnx/csrc/matcha-tts-lexicon.h, sherpa-onnx/csrc/matcha-tts-lexicon.cc
Added bool skip_replacement parameter to public constructors and Impl constructors; added skip_replacement_ member and propagated flag to ProcessPhonemes call sites.
TTS integration updates
sherpa-onnx/csrc/offline-tts-matcha-impl.h, sherpa-onnx/csrc/offline-tts-zipvoice-impl.h
Replaced ZipVoice frontend initialization with MatchaTtsLexicon (passing false for new flag), updated InitFrontend overloads, and changed token extraction to concatenate tokens from all inputs (no longer assuming batch_size == 1).
ZipVoice model config
sherpa-onnx/csrc/offline-tts-zipvoice-model-config.h, sherpa-onnx/csrc/offline-tts-zipvoice-model-config.cc
Added public lexicon member and constructor parameter; removed pinyin_dict existence validation; ToString() now prints lexicon.
ZipVoice model runtime
sherpa-onnx/csrc/offline-tts-zipvoice-model.cc
Replaced exit(-1) with SHERPA_ONNX_EXIT(-1) and refactored a small random-init loop (behavior unchanged).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Check all MatchaTtsLexicon constructor call sites (including templated/Android/OHOS variants) for correct arity and forwarding.
  • Verify removal of OfflineTtsZipvoiceFrontend doesn't leave unresolved symbols or headers.
  • Confirm build scripts and pkg-config template changes do not break platform packaging.

Possibly related PRs

Poem

🐰 I hopped through CMake and pruned a vine,

cppinyin gone, lexicon now shines.
ZipVoice packed up and waved goodbye,
Matcha sorts phonemes, neat and spry.
Tiny paws tidy builds — hop, build, sigh.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Remove cppinyin from zipvoice' directly and concisely describes the primary change across the PR, which systematically removes cppinyin dependencies from build files, CMake configuration, and the zipvoice TTS pipeline.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello @csukuangfj, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request focuses on optimizing and simplifying the ZipVoice Text-to-Speech (TTS) system by removing the cppinyin dependency. This change not only streamlines the project's build and dependency management but also significantly enhances the real-time performance of ZipVoice models. The frontend text processing logic for ZipVoice has been refactored and integrated into the more general MatchaTtsLexicon, leading to a more unified and efficient architecture.

Highlights

  • Dependency Removal: The cppinyin library and all its associated build configurations, source files, and tests have been completely removed from the project. This simplifies the build process and reduces external dependencies.
  • Frontend Consolidation: The custom OfflineTtsZipvoiceFrontend has been removed, and its functionality for ZipVoice models has been integrated into the existing MatchaTtsLexicon. This streamlines the text processing pipeline for TTS.
  • Performance Improvement: This PR results in a significant improvement in Real-Time Factor (RTF) for ZipVoice models, reducing it from 1.117 to 0.897, indicating faster speech synthesis.
  • Model Configuration Update: The ZipVoice model configuration now uses a lexicon parameter instead of pinyin_dict, reflecting the changes in the frontend processing.
  • Token Processing Refinement: Token processing within OfflineTtsZipvoiceImpl has been updated to concatenate tokens from multiple inputs into single vectors, improving how multi-sentence or prompt-based inputs are handled.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request removes the cppinyin dependency for zipvoice TTS, which significantly improves performance by reducing the Real-Time Factor (RTF). The implementation correctly replaces the custom zipvoice frontend with the more general MatchaTtsLexicon, promoting code reuse. The changes across the build files and source code are consistent with the dependency removal.

I have identified an area for improvement regarding the now-deprecated --zipvoice-pinyin-dict parameter, which could lead to user confusion. I've suggested adding a warning to guide users toward the new --zipvoice-lexicon parameter. This change also revealed that the Pascal API has not been fully updated to reflect these changes, which could lead to bugs.

@@ -96,12 +97,6 @@ bool OfflineTtsZipvoiceModelConfig::Validate() const {
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The --zipvoice-pinyin-dict parameter is now deprecated and its value is ignored. To avoid user confusion, it would be beneficial to add a warning if this parameter is still provided. This also helps in guiding users to the new --zipvoice-lexicon parameter.

Additionally, the Pascal API in sherpa-onnx/pascal-api/sherpa_onnx.pas seems to be outdated. It still references PinyinDict and is missing the new Lexicon field in TSherpaOnnxOfflineTtsZipVoiceModelConfig. This should be updated to maintain consistency across APIs and prevent bugs.

Suggested change
if (!pinyin_dict.empty()) {
SHERPA_ONNX_LOGW(
"--zipvoice-pinyin-dict is deprecated and ignored. Please use "
"--zipvoice-lexicon instead.");
}

"Path to tokens.txt for ZipVoice models");
po->Register("zipvoice-data-dir", &data_dir,
"Path to the directory containing dict for espeak-ng.");
po->Register("zipvoice-lexicon", &lexicon, "Plah to lexicon.txt for Chinese");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

There is a typo in the help string for zipvoice-lexicon. 'Plah' should be 'Path'.

Suggested change
po->Register("zipvoice-lexicon", &lexicon, "Plah to lexicon.txt for Chinese");
po->Register("zipvoice-lexicon", &lexicon, "Path to lexicon.txt for Chinese");

@csukuangfj
csukuangfj requested a review from Copilot December 11, 2025 10:45

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (4)
sherpa-onnx/csrc/offline-tts-zipvoice-model-config.cc (1)

42-124: Consider adding validation for the lexicon field.

The new lexicon field is registered and used in InitFrontend but is not validated in Validate(). If lexicon is required for ZipVoice to function correctly, consider adding a check similar to other required files. If it's optional (e.g., only needed for Chinese), document this behavior.

+  if (!lexicon.empty() && !FileExists(lexicon)) {
+    SHERPA_ONNX_LOGE("--zipvoice-lexicon: '%s' does not exist", lexicon.c_str());
+    return false;
+  }
+
   if (feat_scale <= 0) {
sherpa-onnx/csrc/matcha-tts-lexicon.h (1)

22-29: LGTM!

The skip_replacement parameter is consistently added to both constructor signatures. The implementations in the corresponding .cc file correctly forward this parameter.

Consider adding a brief doc comment explaining what skip_replacement controls, as this is now part of the public API.

sherpa-onnx/csrc/offline-tts-matcha-impl.h (1)

380-411: MatchaTtsLexicon ctor updates look consistent and preserve behavior

Both InitFrontend overloads now pass false for the new skip_replacement parameter:

  • Manager-based: MatchaTtsLexicon(mgr, lexicon, tokens, data_dir, debug, false)
  • Non-manager: MatchaTtsLexicon(lexicon, tokens, data_dir, debug, false)

This matches the updated constructor signature (..., data_dir, bool debug, bool skip_replacement) and keeps the previous default behavior (replacements enabled) for existing Matcha models, which is what you want for a drop-in change.

If you foresee some Matcha models wanting different behavior, consider eventually threading this flag from config instead of hard-coding false, but that’s strictly optional for now.

sherpa-onnx/csrc/matcha-tts-lexicon.cc (1)

125-135: skip_replacement toggle is correctly wired through phoneme processing

The new skip_replacement flow in ProcessPhonemes and its use via skip_replacement_ in ConvertWordToIds look sound:

  • ProcessPhonemes(phonemes, skip_replacement):
    • When skip_replacement is false, behavior matches the previous implementation (UTF-8 conversion, full replacement pipeline, and UTF-8 splitting).
    • When true, it returns the raw UTF‑8 phoneme tokens, cleanly bypassing replacements.
  • skip_replacement_ is stored in Impl and used only in the espeak OOV path, which is exactly where the replacement behavior matters.

This gives a clear, low-risk control knob while preserving existing behavior for callers that pass false.

A tiny nit: the trailing comment on the Impl closing brace still says // namespace sherpa_onnx, which is misleading — consider updating it the next time you touch this file.

Also applies to: 367-375, 483-485

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 42dcaf1 and 11b0284.

📒 Files selected for processing (22)
  • CMakeLists.txt (0 hunks)
  • build-ios.sh (1 hunks)
  • build-swift-macos.sh (0 hunks)
  • c-api-examples/Makefile (1 hunks)
  • cmake/cppinyin.cmake (0 hunks)
  • cmake/cppinyin.patch (0 hunks)
  • cmake/sherpa-onnx-static.pc.in (1 hunks)
  • mfc-examples/NonStreamingSpeechRecognition/sherpa-onnx-deps.props (0 hunks)
  • mfc-examples/NonStreamingTextToSpeech/sherpa-onnx-deps.props (0 hunks)
  • mfc-examples/StreamingSpeechRecognition/sherpa-onnx-deps.props (0 hunks)
  • sherpa-onnx/csrc/CMakeLists.txt (0 hunks)
  • sherpa-onnx/csrc/matcha-tts-lexicon.cc (6 hunks)
  • sherpa-onnx/csrc/matcha-tts-lexicon.h (1 hunks)
  • sherpa-onnx/csrc/offline-tts-matcha-impl.h (2 hunks)
  • sherpa-onnx/csrc/offline-tts-zipvoice-frontend-test.cc (0 hunks)
  • sherpa-onnx/csrc/offline-tts-zipvoice-frontend.cc (0 hunks)
  • sherpa-onnx/csrc/offline-tts-zipvoice-frontend.h (0 hunks)
  • sherpa-onnx/csrc/offline-tts-zipvoice-impl.h (3 hunks)
  • sherpa-onnx/csrc/offline-tts-zipvoice-model-config.cc (2 hunks)
  • sherpa-onnx/csrc/offline-tts-zipvoice-model-config.h (2 hunks)
  • sherpa-onnx/csrc/offline-tts-zipvoice-model.cc (2 hunks)
  • sherpa-onnx/pascal-api/sherpa_onnx.pas (0 hunks)
💤 Files with no reviewable changes (12)
  • mfc-examples/StreamingSpeechRecognition/sherpa-onnx-deps.props
  • CMakeLists.txt
  • cmake/cppinyin.cmake
  • build-swift-macos.sh
  • mfc-examples/NonStreamingTextToSpeech/sherpa-onnx-deps.props
  • sherpa-onnx/pascal-api/sherpa_onnx.pas
  • mfc-examples/NonStreamingSpeechRecognition/sherpa-onnx-deps.props
  • sherpa-onnx/csrc/offline-tts-zipvoice-frontend.h
  • sherpa-onnx/csrc/offline-tts-zipvoice-frontend-test.cc
  • cmake/cppinyin.patch
  • sherpa-onnx/csrc/CMakeLists.txt
  • sherpa-onnx/csrc/offline-tts-zipvoice-frontend.cc
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-06T04:23:50.237Z
Learnt from: litongjava
Repo: k2-fsa/sherpa-onnx PR: 2440
File: sherpa-onnx/java-api/src/main/java/com/k2fsa/sherpa/onnx/core/Core.java:4-6
Timestamp: 2025-08-06T04:23:50.237Z
Learning: The sherpa-onnx JNI library files are stored in Hugging Face repository at https://huggingface.co/csukuangfj/sherpa-onnx-libs under versioned directories like jni/1.12.7/, and the actual Windows JNI library filename is "sherpa-onnx-jni.dll" as defined in Core.java constants.

Applied to files:

  • build-ios.sh
  • cmake/sherpa-onnx-static.pc.in
  • sherpa-onnx/csrc/offline-tts-zipvoice-impl.h
📚 Learning: 2025-08-06T04:18:47.981Z
Learnt from: litongjava
Repo: k2-fsa/sherpa-onnx PR: 2440
File: sherpa-onnx/java-api/src/main/java/com/k2fsa/sherpa/onnx/core/Core.java:4-6
Timestamp: 2025-08-06T04:18:47.981Z
Learning: In sherpa-onnx Java API, the native library names in Core.java (WIN_NATIVE_LIBRARY_NAME = "sherpa-onnx-jni.dll", UNIX_NATIVE_LIBRARY_NAME = "libsherpa-onnx-jni.so", MACOS_NATIVE_LIBRARY_NAME = "libsherpa-onnx-jni.dylib") are copied directly from the compiled binary filenames and should not be changed to match other libraries' naming conventions.

Applied to files:

  • build-ios.sh
  • cmake/sherpa-onnx-static.pc.in
  • sherpa-onnx/csrc/offline-tts-zipvoice-impl.h
🧬 Code graph analysis (5)
sherpa-onnx/csrc/offline-tts-zipvoice-impl.h (2)
sherpa-onnx/csrc/offline-tts-zipvoice-model.cc (2)
  • tokens (60-191)
  • tokens (60-61)
sherpa-onnx/csrc/matcha-tts-lexicon.h (1)
  • MatchaTtsLexicon (18-38)
sherpa-onnx/csrc/matcha-tts-lexicon.h (1)
sherpa-onnx/csrc/matcha-tts-lexicon.cc (7)
  • MatchaTtsLexicon (487-487)
  • MatchaTtsLexicon (489-494)
  • MatchaTtsLexicon (497-502)
  • MatchaTtsLexicon (510-514)
  • MatchaTtsLexicon (518-522)
  • lexicon (405-417)
  • lexicon (405-405)
sherpa-onnx/csrc/offline-tts-zipvoice-model-config.cc (1)
sherpa-onnx/csrc/matcha-tts-lexicon.cc (2)
  • lexicon (405-417)
  • lexicon (405-405)
sherpa-onnx/csrc/offline-tts-zipvoice-model-config.h (2)
sherpa-onnx/csrc/matcha-tts-lexicon.cc (2)
  • lexicon (405-417)
  • lexicon (405-405)
sherpa-onnx/csrc/offline-tts-zipvoice-model.cc (2)
  • tokens (60-191)
  • tokens (60-61)
sherpa-onnx/csrc/matcha-tts-lexicon.cc (1)
sherpa-onnx/csrc/matcha-tts-lexicon.h (1)
  • MatchaTtsLexicon (18-38)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: Release shared tts-ON
  • GitHub Check: Release shared tts-OFF
  • GitHub Check: Debug static tts-OFF
  • GitHub Check: Debug shared tts-OFF
  • GitHub Check: rknn shared ON
  • GitHub Check: Release shared-OFF tts-OFF
  • GitHub Check: ubuntu-24.04 3.10
  • GitHub Check: Debug shared-OFF tts-OFF
  • GitHub Check: Release shared-ON tts-ON
  • GitHub Check: Debug shared-OFF tts-ON
  • GitHub Check: ubuntu-24.04 3.8
  • GitHub Check: ubuntu-24.04 3.9
  • GitHub Check: Release shared-ON tts-OFF
  • GitHub Check: Debug shared-ON tts-ON
  • GitHub Check: ubuntu-24.04 3.11
  • GitHub Check: ubuntu-24.04 3.12
  • GitHub Check: Debug shared-ON tts-OFF
  • GitHub Check: ubuntu-24.04 3.13
  • GitHub Check: Release shared-OFF tts-ON
  • GitHub Check: swift (macos-latest)
🔇 Additional comments (12)
sherpa-onnx/csrc/offline-tts-zipvoice-model.cc (2)

71-71: LGTM!

Using SHERPA_ONNX_EXIT(-1) instead of raw exit(-1) is correct for cross-platform consistency with the project's macro conventions.


111-114: LGTM!

The explicit range-based for loop is clearer and maintains the same behavior as the previous implementation.

sherpa-onnx/csrc/offline-tts-zipvoice-impl.h (3)

18-18: LGTM!

The new include for matcha-tts-lexicon.h correctly supports the frontend replacement from OfflineTtsZipvoiceFrontend to MatchaTtsLexicon.


86-95: LGTM!

The change from single-element extraction (text_token_ids[0].tokens) to concatenating all TokenIDs entries correctly supports multi-segment text inputs, which is important when the frontend splits text into multiple token sequences.


104-112: Verify that skip_replacement=true is the intended behavior for ZipVoice.

The MatchaTtsLexicon is instantiated with skip_replacement hardcoded to true. Ensure this is intentional for the ZipVoice use case, as it affects phoneme processing behavior.

sherpa-onnx/csrc/offline-tts-zipvoice-model-config.h (2)

22-22: LGTM!

The new lexicon member is correctly placed after data_dir, aligning with the PR's goal to support lexicon-based text processing.


34-50: LGTM!

The constructor signature and initializer list are correctly updated to include the new lexicon parameter in proper order.

sherpa-onnx/csrc/offline-tts-zipvoice-model-config.cc (1)

136-136: LGTM!

The ToString() method correctly outputs the new lexicon field for debugging and logging purposes.

sherpa-onnx/csrc/matcha-tts-lexicon.cc (1)

145-199: Constructor and explicit instantiation updates for skip_replacement are consistent

The additional bool skip_replacement parameter is threaded cleanly:

  • MatchaTtsLexicon::Impl constructors now take (..., data_dir, bool debug, bool skip_replacement) and initialize both debug_ and skip_replacement_.
  • Public MatchaTtsLexicon constructors mirror that signature and forward to Impl.
  • The templated MatchaTtsLexicon(Manager *mgr, ...) and the explicit instantiations for AAssetManager and NativeResourceManager are all updated to include skip_replacement at the end, matching the header declaration.

This ensures all creation paths (regular, Android, OHOS) see the new flag consistently, with no dangling old-signature usage.

Also applies to: 489-503, 510-515, 518-523

cmake/sherpa-onnx-static.pc.in (1)

22-25: cppinyin_core cleanly removed from static pkg-config Libs

The Libs line now omits -lcppinyin_core while preserving the existing library list and rpath flag, which aligns with dropping cppinyin from the build without disturbing other consumers.

Please regenerate and use the resulting sherpa-onnx-static.pc in a downstream project once to confirm static linking works as expected without cppinyin_core.

c-api-examples/Makefile (1)

4-11: Example linker flags updated consistently with cppinyin removal

The LDFLAGS library list drops cppinyin_core and remains consistent with the core/static configuration; rpaths still cover both the sherpa-onnx and ONNX Runtime library directories, so example binaries should keep running.

After this change, please rebuild decode-file-c-api and offline-tts-c-api to confirm there are no missing symbols at link or run time.

build-ios.sh (1)

129-137: Universal simulator archive list correctly drops libcppinyin_core.a

The loop that creates universal simulator archives now excludes libcppinyin_core.a while keeping the set of libraries aligned with those later merged into libsherpa-onnx.a, so xcframework generation should no longer depend on cppinyin.

Please run build-ios.sh once on a clean tree to verify lipo, libtool, and xcodebuild -create-xcframework all complete without missing-archive errors.

Comment thread sherpa-onnx/csrc/offline-tts-zipvoice-model-config.cc Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
sherpa-onnx/csrc/offline-tts-zipvoice-model-config.cc (1)

21-23: Add deprecation warning for --zipvoice-pinyin-dict.

The parameter is still registered but silently ignored after the migration to lexicon-based tokenization. Users who provide this parameter will not receive any feedback that it's no longer used, potentially causing confusion.

Based on previous review feedback that has not yet been addressed.

Consider adding a warning in the Validate() method:

+  if (!pinyin_dict.empty()) {
+    SHERPA_ONNX_LOGW(
+        "--zipvoice-pinyin-dict is deprecated and ignored. Please use "
+        "--zipvoice-lexicon instead.");
+  }
+
   if (feat_scale <= 0) {
🧹 Nitpick comments (1)
sherpa-onnx/csrc/offline-tts-zipvoice-model-config.cc (1)

42-125: Consider validating lexicon parameter if provided.

While InitLexicon will handle errors at runtime, validating the lexicon path(s) during configuration would provide earlier feedback to users. Following the pattern used for data_dir (lines 83-98), you could check file existence when lexicon is non-empty.

Example validation (can be added after the data_dir validation block):

  if (!lexicon.empty()) {
    std::vector<std::string> files;
    SplitStringToVector(lexicon, ",", false, &files);
    for (const auto &f : files) {
      if (!FileExists(f)) {
        SHERPA_ONNX_LOGE("--zipvoice-lexicon: '%s' does not exist", f.c_str());
        return false;
      }
    }
  }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 11b0284 and 6d63ab1.

📒 Files selected for processing (1)
  • sherpa-onnx/csrc/offline-tts-zipvoice-model-config.cc (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
sherpa-onnx/csrc/offline-tts-zipvoice-model-config.cc (1)
sherpa-onnx/csrc/matcha-tts-lexicon.cc (2)
  • lexicon (405-417)
  • lexicon (405-405)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (19)
  • GitHub Check: Release static tts-OFF
  • GitHub Check: Debug static tts-OFF
  • GitHub Check: swift (macos-latest)
  • GitHub Check: rknn shared OFF
  • GitHub Check: rknn shared ON
  • GitHub Check: Release shared-ON tts-ON
  • GitHub Check: Debug shared-ON tts-ON
  • GitHub Check: Debug shared-OFF tts-OFF
  • GitHub Check: Debug shared-OFF tts-ON
  • GitHub Check: Release shared-ON tts-OFF
  • GitHub Check: Release shared-OFF tts-ON
  • GitHub Check: Debug shared-ON tts-OFF
  • GitHub Check: Release shared-OFF tts-OFF
  • GitHub Check: ubuntu-24.04 3.13
  • GitHub Check: ubuntu-24.04 3.11
  • GitHub Check: ubuntu-24.04 3.8
  • GitHub Check: ubuntu-24.04 3.12
  • GitHub Check: ubuntu-24.04 3.10
  • GitHub Check: ubuntu-24.04 3.9
🔇 Additional comments (2)
sherpa-onnx/csrc/offline-tts-zipvoice-model-config.cc (2)

26-27: Good clarification that flow-matching-model is the decoder.

This documentation improvement helps users understand the model architecture.


127-143: ToString correctly reflects the lexicon field.

The serialization properly outputs the new lexicon field, maintaining consistency with the migration from pinyin_dict to lexicon-based tokenization.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR removes the cppinyin dependency from the ZipVoice TTS implementation, improving performance (RTF reduced from 1.117 to 0.897) by switching from a custom frontend implementation to the existing MatchaTtsLexicon class. The change simplifies the codebase by eliminating redundant Chinese text processing code and standardizing on a common lexicon-based approach.

Key Changes:

  • Replaced custom ZipVoice frontend with MatchaTtsLexicon, adding lexicon parameter support
  • Removed cppinyin library dependency from build system across all platforms (CMake, iOS, macOS, Pascal, MFC examples)
  • Enhanced MatchaTtsLexicon with skip_replacement parameter to support different phoneme processing requirements

Reviewed changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
sherpa-onnx/csrc/offline-tts-zipvoice-impl.h Replaced OfflineTtsZipvoiceFrontend with MatchaTtsLexicon and added token flattening logic
sherpa-onnx/csrc/offline-tts-zipvoice-model-config.h Added lexicon field to config struct
sherpa-onnx/csrc/offline-tts-zipvoice-model-config.cc Added lexicon parameter registration and removed pinyin_dict validation
sherpa-onnx/csrc/offline-tts-zipvoice-model.cc Replaced exit() with SHERPA_ONNX_EXIT() and improved code style
sherpa-onnx/csrc/offline-tts-zipvoice-frontend.h Deleted - custom frontend no longer needed
sherpa-onnx/csrc/offline-tts-zipvoice-frontend.cc Deleted - custom frontend implementation removed
sherpa-onnx/csrc/offline-tts-zipvoice-frontend-test.cc Deleted - test file for removed frontend
sherpa-onnx/csrc/matcha-tts-lexicon.h Added skip_replacement parameter to support ZipVoice requirements
sherpa-onnx/csrc/matcha-tts-lexicon.cc Implemented skip_replacement logic to bypass phoneme replacements
sherpa-onnx/csrc/offline-tts-matcha-impl.h Updated calls to MatchaTtsLexicon with skip_replacement=false
sherpa-onnx/csrc/CMakeLists.txt Removed offline-tts-zipvoice-frontend.cc and cppinyin_core dependency
CMakeLists.txt Removed cppinyin.cmake include
cmake/cppinyin.cmake Deleted - cppinyin download/build script no longer needed
cmake/cppinyin.patch Deleted - cppinyin patch file no longer needed
cmake/sherpa-onnx-static.pc.in Removed -lcppinyin_core from static library linking
build-ios.sh Removed libcppinyin_core.a from iOS library merging
build-swift-macos.sh Removed libcppinyin_core.a from macOS library merging
c-api-examples/Makefile Removed -lcppinyin_core from linker flags
sherpa-onnx/pascal-api/sherpa_onnx.pas Removed cppinyin_core library linkage
mfc-examples/*/sherpa-onnx-deps.props Removed cppinyin_core.lib from MFC example dependencies

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 22 to 23
"Path to the pinyin dictionary for cppinyin (i.e converting "
"Chinese into phones).");

Copilot AI Dec 11, 2025

Copy link

Choose a reason for hiding this comment

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

The help text for zipvoice-pinyin-dict references cppinyin, which is being removed in this PR. Since pinyin_dict is no longer used, consider updating this help text to indicate it is deprecated or remove the parameter entirely in a future cleanup.

Suggested change
"Path to the pinyin dictionary for cppinyin (i.e converting "
"Chinese into phones).");
"DEPRECATED: This parameter is no longer used and will be removed in a future release.");

Copilot uses AI. Check for mistakes.
"Path to tokens.txt for ZipVoice models");
po->Register("zipvoice-data-dir", &data_dir,
"Path to the directory containing dict for espeak-ng.");
po->Register("zipvoice-lexicon", &lexicon, "Path to lexicon.txt for Chinese");

Copilot AI Dec 11, 2025

Copy link

Choose a reason for hiding this comment

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

Typo in help text: "Plah" should be "Path".

Copilot uses AI. Check for mistakes.
std::string data_dir;
std::string lexicon;

// Used for converting Chinese characters to pinyin

Copilot AI Dec 11, 2025

Copy link

Choose a reason for hiding this comment

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

The comment "Used for converting Chinese characters to pinyin" for the pinyin_dict field is outdated and misleading. Since this PR removes cppinyin dependency and the pinyin_dict is no longer validated or used in the implementation, this comment should either be removed or updated to indicate it is deprecated/unused.

Suggested change
// Used for converting Chinese characters to pinyin
// Deprecated/unused: previously used for converting Chinese characters to pinyin

Copilot uses AI. Check for mistakes.
@csukuangfj
csukuangfj merged commit 1b59efd into k2-fsa:master Dec 11, 2025
17 of 27 checks passed
@csukuangfj
csukuangfj deleted the refactor-zipvoice-cpp branch December 11, 2025 10:57
}
}

std::vector<TokenIDs> OfflineTtsZipvoiceFrontend::ConvertTextToTokenIds(

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.

Have you read all this logic? You just removed all of them? If you don't like cppinyin, you can replace it with jieba + table lookup, but I think you should be careful to remove the whole frontend.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yes, this part of the code mirrors the Python frontend and supports constructs such as [] and <>.
Users can update lexicon.txt to specify the correct pronunciations of Chinese words. This model does not support [S1], [S2], or similar tags; removing them does not affect model behavior and results in less code and lower maintenance effort.

This is not about a preference for or against cppinyin; the goal is to keep the code concise and reusable across models.

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.

OK, [S1], [S2] is for zipvoice dialog, have not supported yet. Well, it's up to you, most of time, it is you who maintain this repo.

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

Labels

size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants