mirror of
https://github.com/modelscope/FunASR.git
synced 2026-10-12 02:19:18 +00:00
fix(realtime): preserve aligned long-segment partials (#3589)
Signed-off-by: LauraGPT <[email protected]> Co-authored-by: LauraGPT <[email protected]>
This commit is contained in:
@@ -13,6 +13,7 @@ Features:
|
||||
import asyncio
|
||||
from collections import deque
|
||||
import copy
|
||||
from difflib import SequenceMatcher
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
@@ -1104,24 +1105,31 @@ class RealtimeASRSession:
|
||||
):
|
||||
final_cmp = _normalize_transcript(final_text)
|
||||
recent_cmp = _normalize_transcript(recent_partial)
|
||||
common_prefix_len = 0
|
||||
for final_char, partial_char in zip(final_cmp, recent_cmp):
|
||||
if final_char != partial_char:
|
||||
break
|
||||
common_prefix_len += 1
|
||||
diverged = common_prefix_len < min(len(final_cmp), len(recent_cmp))
|
||||
matcher = SequenceMatcher(None, final_cmp, recent_cmp, autojunk=False)
|
||||
matching_blocks = matcher.get_matching_blocks()
|
||||
matched_chars = sum(block.size for block in matching_blocks)
|
||||
final_coverage = matched_chars / max(1, len(final_cmp))
|
||||
first_match = next(
|
||||
(block for block in matching_blocks if block.size), None
|
||||
)
|
||||
starts_aligned = bool(
|
||||
first_match and first_match.a <= 1 and first_match.b <= 2
|
||||
)
|
||||
diverged = final_cmp != recent_cmp
|
||||
catastrophically_short = (
|
||||
diverged
|
||||
and len(final_cmp) >= 2
|
||||
and len(final_cmp) >= 1
|
||||
and len(recent_cmp) >= 24
|
||||
and len(recent_cmp) >= len(final_cmp) * 3
|
||||
and common_prefix_len >= max(1, len(final_cmp) // 2)
|
||||
and starts_aligned
|
||||
and matched_chars >= max(1, len(final_cmp) // 2)
|
||||
)
|
||||
tail_regressed = (
|
||||
diverged
|
||||
and len(final_cmp) >= 16
|
||||
and len(recent_cmp) - len(final_cmp) >= 4
|
||||
and common_prefix_len >= max(12, (len(final_cmp) * 3) // 4)
|
||||
and starts_aligned
|
||||
and final_coverage >= 0.75
|
||||
)
|
||||
if catastrophically_short or tail_regressed:
|
||||
partial_text = recent_partial
|
||||
|
||||
@@ -550,6 +550,48 @@ def test_long_segment_recovers_from_catastrophically_short_final():
|
||||
assert text == partial
|
||||
|
||||
|
||||
def test_long_segment_recovers_from_single_character_final():
|
||||
module = load_service_module()
|
||||
partial = (
|
||||
"哎,不好意思,上午高雄交通比较混乱一点,我们不晓得我们有点。"
|
||||
"胡总,各位长官。"
|
||||
)
|
||||
session = make_reported_long_segment_reconciliation_session(
|
||||
module, partial, partial_end_ms=35328
|
||||
)
|
||||
|
||||
text = session._reconcile_completed_segment_text(
|
||||
"哎",
|
||||
[2920, 36260],
|
||||
decode_succeeded=True,
|
||||
)
|
||||
|
||||
assert text == partial
|
||||
|
||||
|
||||
def test_long_segment_recovers_when_an_early_partial_correction_hides_tail_regression():
|
||||
module = load_service_module()
|
||||
partial = (
|
||||
"哇,哎,不好意思,上午杭高雄的交通比较混乱一点,我们不晓得我们有点。"
|
||||
"哎,好嘞,胡总各位长官。"
|
||||
)
|
||||
final = (
|
||||
"哇,不好意思,上午高雄的交通比较混乱一点,我们不晓得我们有点。"
|
||||
"哎,好嘞,"
|
||||
)
|
||||
session = make_reported_long_segment_reconciliation_session(
|
||||
module, partial, partial_end_ms=14336
|
||||
)
|
||||
|
||||
text = session._reconcile_completed_segment_text(
|
||||
final,
|
||||
[2920, 14420],
|
||||
decode_succeeded=True,
|
||||
)
|
||||
|
||||
assert text == partial
|
||||
|
||||
|
||||
def test_long_segment_keeps_distinct_short_final_without_prefix_alignment():
|
||||
module = load_service_module()
|
||||
partial = "会议取消,稍后另行通知,请各位等待后续的完整安排和确认消息。"
|
||||
|
||||
Reference in New Issue
Block a user