Skip to content

fix: split long text into chunks to prevent distortion on long inputs (#372) - #391

Open
ousamabenyounes wants to merge 1 commit into
OpenBMB:mainfrom
ousamabenyounes:fix/issue-372
Open

fix: split long text into chunks to prevent distortion on long inputs (#372)#391
ousamabenyounes wants to merge 1 commit into
OpenBMB:mainfrom
ousamabenyounes:fix/issue-372

Conversation

@ousamabenyounes

Copy link
Copy Markdown

Long single-shot generations degrade into distortion past a few hundred characters (worse on VoxCPM2). VoxCPM._generate now splits long text on sentence boundaries into <=max_chunk_chars chunks and synthesizes each with the same prompt cache, keeping every generation short while preserving the voice.

Test verification (RED → GREEN)

With the fix reverted, the new test fails (RED):

        text = "这是一段很长的测试文本。" * 10  # ~120 chars
    
>       out = list(vox._generate(text, streaming=False, max_chunk_chars=MAX_CHARS))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E       TypeError: VoxCPM._generate() got an unexpected keyword argument 'max_chunk_chars'

tests/test_long_text_chunking.py:153: TypeError
___________________ test_generate_short_text_is_single_call ____________________

    def test_generate_short_text_is_single_call():
        model = _RecordingModel()
        vox = _make_vox(model)
        text = "短文本。"
    
>       list(vox._generate(text, streaming=False, max_chunk_chars=MAX_CHARS))
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E       TypeError: VoxCPM._generate() got an unexpected keyword argument 'max_chunk_chars'

tests/test_long_text_chunking.py:170: TypeError
__________________ test_generate_streaming_yields_each_chunk ___________________

    def test_generate_streaming_yields_each_chunk():
        model = _RecordingModel()
        vox = _make_vox(model)
        text = "流式测试的句子。" * 8
    
>       out = list(vox._generate(text, streaming=True, max_chunk_chars=MAX_CHARS))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E       TypeError: VoxCPM._generate() got an unexpected keyword argument 'max_chunk_chars'

tests/test_long_text_chunking.py:181: TypeError
=========================== short test summary info ============================
FAILED tests/test_long_text_chunking.py::test_short_text_is_single_chunk - At...
FAILED tests/test_long_text_chunking.py::test_long_text_splits_on_sentence_boundaries
FAILED tests/test_long_text_chunking.py::test_splitting_disabled_when_max_chars_non_positive
FAILED tests/test_long_text_chunking.py::test_sentence_without_delimiter_is_hard_sliced
FAILED tests/test_long_text_chunking.py::test_generate_chunks_long_text_into_multiple_calls
FAILED tests/test_long_text_chunking.py::test_generate_short_text_is_single_call
FAILED tests/test_long_text_chunking.py::test_generate_streaming_yields_each_chunk
============================== 7 failed in 0.08s ===============================

With the fix applied, the test passes (GREEN):

GREEN attempt 1/2 (exit 0)
============================= test session starts ==============================
platform linux -- Python 3.14.4, pytest-9.0.2, pluggy-1.6.0 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /home/ousama/contribute-work/OpenBMB__VoxCPM
configfile: pyproject.toml
plugins: typeguard-4.4.4
collecting ... collected 7 items

tests/test_long_text_chunking.py::test_short_text_is_single_chunk PASSED
tests/test_long_text_chunking.py::test_long_text_splits_on_sentence_boundaries PASSED
tests/test_long_text_chunking.py::test_splitting_disabled_when_max_chars_non_positive PASSED
tests/test_long_text_chunking.py::test_sentence_without_delimiter_is_hard_sliced PASSED
tests/test_long_text_chunking.py::test_generate_chunks_long_text_into_multiple_calls long text -> 4 chunks, audio samples=120
PASSED
tests/test_long_text_chunking.py::test_generate_short_text_is_single_call short text -> 1 chunk
PASSED
tests/test_long_text_chunking.py::test_generate_streaming_yields_each_chunk streaming long text -> 2 chunks yielded
PASSED

============================== 7 passed in 0.06s ===============================

Full local suite

Command: python3 -m pytest tests/

============================= test session starts ==============================
platform linux -- Python 3.14.4, pytest-9.0.2, pluggy-1.6.0
rootdir: /home/ousama/contribute-work/OpenBMB__VoxCPM
configfile: pyproject.toml
plugins: typeguard-4.4.4
collected 52 items / 2 errors

==================================== ERRORS ====================================
____________ ERROR collecting tests/test_lora_checkpoint_loading.py ____________
ImportError while importing test module '/home/ousama/contribute-work/OpenBMB__VoxCPM/tests/test_lora_checkpoint_loading.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.14/importlib/__init__.py:88: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
tests/test_lora_checkpoint_loading.py:9: in <module>
    import torch
E   ModuleNotFoundError: No module named 'torch'
__________________ ERROR collecting tests/test_model_utils.py __________________
ImportError while importing test module '/home/ousama/contribute-work/OpenBMB__VoxCPM/tests/test_model_utils.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.14/importlib/__init__.py:88: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
tests/test_model_utils.py:20: in <module>
    spec.loader.exec_module(utils)
src/voxcpm/model/utils.py:3: in <module>
    import torch
E   ModuleNotFoundError: No module named 'torch'
=========================== short test summary info ============================
ERROR tests/test_lora_checkpoint_loading.py
ERROR tests/test_model_utils.py
!!!!!!!!!!!!!!!!!!! Interrupted: 2 errors during collection !!!!!!!!!!!!!!!!!!!!
============================== 2 errors in 0.16s ===============================

Fix #372

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

长文本声音失真严重问题

1 participant