Spaces:
Running on Zero
Running on Zero
Codex commited on
Commit ·
ca45ff1
1
Parent(s): 0382000
Bind release evidence to verified text variants
Browse files- app.py +76 -1
- quality_runtime.py +33 -1
- tests/test_coverage_adaptive.py +87 -1
- tests/test_production.py +31 -0
- tests/test_quality_runtime.py +1 -1
- tests/test_release_pins.py +160 -3
app.py
CHANGED
|
@@ -154,6 +154,8 @@ MAX_TEXT_CHARS = 360
|
|
| 154 |
QUALITY_MAX_GENERATED_CHUNKS = 32
|
| 155 |
QUALITY_MAX_GENERATED_TEXT_UNITS = 800
|
| 156 |
EMAIL_MAIL_FALLBACK_CANDIDATE_ORDINALS = frozenset((2, 5, 6))
|
|
|
|
|
|
|
| 157 |
QUALITY_FINAL_ASR_MAX_NEW_TOKENS = 440
|
| 158 |
QUALITY_MAX_CER = 0.20
|
| 159 |
QUALITY_MAX_PACE_CPS = 4.30
|
|
@@ -1327,7 +1329,26 @@ def _verify_sequence_trajectory_audio(
|
|
| 1327 |
f"chunk_candidates={sequence_result.chunk_candidate_indices} "
|
| 1328 |
f"{_verification_metric_log_fields(assembled_verification)}"
|
| 1329 |
)
|
| 1330 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1331 |
|
| 1332 |
|
| 1333 |
def _synthesize(
|
|
@@ -1451,6 +1472,48 @@ def _synthesize(
|
|
| 1451 |
)
|
| 1452 |
return tuple(transformed)
|
| 1453 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1454 |
def generation_chunk_specs(
|
| 1455 |
seed: int,
|
| 1456 |
candidate_chunks: tuple[str, ...],
|
|
@@ -1615,6 +1678,17 @@ def _synthesize(
|
|
| 1615 |
candidate_chunks,
|
| 1616 |
generation_context=generation_context,
|
| 1617 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1618 |
rows = tuple(
|
| 1619 |
chunk_cfg_evidence(
|
| 1620 |
chunk,
|
|
@@ -1637,6 +1711,7 @@ def _synthesize(
|
|
| 1637 |
floor_reasons=tuple(row[1] for row in rows),
|
| 1638 |
chunk_candidate_ordinals=candidate_ordinals,
|
| 1639 |
network_conditioned=network_flags,
|
|
|
|
| 1640 |
)
|
| 1641 |
|
| 1642 |
try:
|
|
|
|
| 154 |
QUALITY_MAX_GENERATED_CHUNKS = 32
|
| 155 |
QUALITY_MAX_GENERATED_TEXT_UNITS = 800
|
| 156 |
EMAIL_MAIL_FALLBACK_CANDIDATE_ORDINALS = frozenset((2, 5, 6))
|
| 157 |
+
BASE_CHUNK_TEXT_VARIANT = "base"
|
| 158 |
+
EMAIL_DOMAIN_MAIL_CHUNK_TEXT_VARIANT = "email_domain_mail_v1"
|
| 159 |
QUALITY_FINAL_ASR_MAX_NEW_TOKENS = 440
|
| 160 |
QUALITY_MAX_CER = 0.20
|
| 161 |
QUALITY_MAX_PACE_CPS = 4.30
|
|
|
|
| 1329 |
f"chunk_candidates={sequence_result.chunk_candidate_indices} "
|
| 1330 |
f"{_verification_metric_log_fields(assembled_verification)}"
|
| 1331 |
)
|
| 1332 |
+
if not assembled_verification.passed:
|
| 1333 |
+
return assembled_verification
|
| 1334 |
+
independent_verification = _verify_independent_whole_audio(
|
| 1335 |
+
waveform,
|
| 1336 |
+
whole_target_text,
|
| 1337 |
+
anchor,
|
| 1338 |
+
independent_cache,
|
| 1339 |
+
)
|
| 1340 |
+
intersected = qualify_trajectory_with_joined_output(
|
| 1341 |
+
assembled_verification,
|
| 1342 |
+
independent_verification,
|
| 1343 |
+
)
|
| 1344 |
+
independent_status = "verified" if independent_verification.passed else "rejected"
|
| 1345 |
+
print(
|
| 1346 |
+
f"[BlueMagpie] sequence path independent large-v3 {independent_status} "
|
| 1347 |
+
f"rank={sequence_result.sequence_path_rank} "
|
| 1348 |
+
f"chunk_candidates={sequence_result.chunk_candidate_indices} "
|
| 1349 |
+
f"{_verification_metric_log_fields(independent_verification)}"
|
| 1350 |
+
)
|
| 1351 |
+
return intersected
|
| 1352 |
|
| 1353 |
|
| 1354 |
def _synthesize(
|
|
|
|
| 1472 |
)
|
| 1473 |
return tuple(transformed)
|
| 1474 |
|
| 1475 |
+
def candidate_generation_text_variants(
|
| 1476 |
+
canonical_chunks: tuple[str, ...],
|
| 1477 |
+
generation_context: CandidateGenerationContext,
|
| 1478 |
+
) -> tuple[str, ...]:
|
| 1479 |
+
expected_canonical = canonical_chunks_for_context(generation_context)
|
| 1480 |
+
if canonical_chunks != expected_canonical:
|
| 1481 |
+
raise ValueError("candidate text variant lacks canonical provenance")
|
| 1482 |
+
generated_chunks = candidate_generation_text_transform(
|
| 1483 |
+
canonical_chunks,
|
| 1484 |
+
generation_context,
|
| 1485 |
+
)
|
| 1486 |
+
variants: list[str] = []
|
| 1487 |
+
for chunk_index, canonical, generated, candidate_ordinal in zip(
|
| 1488 |
+
generation_context.chunk_indices,
|
| 1489 |
+
canonical_chunks,
|
| 1490 |
+
generated_chunks,
|
| 1491 |
+
generation_context.chunk_candidate_ordinals,
|
| 1492 |
+
strict=True,
|
| 1493 |
+
):
|
| 1494 |
+
if generated == canonical:
|
| 1495 |
+
variants.append(BASE_CHUNK_TEXT_VARIANT)
|
| 1496 |
+
continue
|
| 1497 |
+
if chunk_specs is None:
|
| 1498 |
+
raise ValueError("candidate text variant lacks network proof")
|
| 1499 |
+
spec = chunk_specs[chunk_index]
|
| 1500 |
+
expected_variant = email_domain_mail_generation_variant(
|
| 1501 |
+
canonical,
|
| 1502 |
+
spec.network_fragment_proofs,
|
| 1503 |
+
)
|
| 1504 |
+
if (
|
| 1505 |
+
candidate_ordinal not in EMAIL_MAIL_FALLBACK_CANDIDATE_ORDINALS
|
| 1506 |
+
or generated != expected_variant
|
| 1507 |
+
or generated == canonical
|
| 1508 |
+
or not any(
|
| 1509 |
+
proof.identifier_kind == "email"
|
| 1510 |
+
for proof in spec.network_fragment_proofs
|
| 1511 |
+
)
|
| 1512 |
+
):
|
| 1513 |
+
raise ValueError("candidate text variant is not proof-bound")
|
| 1514 |
+
variants.append(EMAIL_DOMAIN_MAIL_CHUNK_TEXT_VARIANT)
|
| 1515 |
+
return tuple(variants)
|
| 1516 |
+
|
| 1517 |
def generation_chunk_specs(
|
| 1518 |
seed: int,
|
| 1519 |
candidate_chunks: tuple[str, ...],
|
|
|
|
| 1678 |
candidate_chunks,
|
| 1679 |
generation_context=generation_context,
|
| 1680 |
)
|
| 1681 |
+
canonical_chunks = canonical_chunks_for_context(generation_context)
|
| 1682 |
+
expected_generation_chunks = candidate_generation_text_transform(
|
| 1683 |
+
canonical_chunks,
|
| 1684 |
+
generation_context,
|
| 1685 |
+
)
|
| 1686 |
+
if candidate_chunks != expected_generation_chunks:
|
| 1687 |
+
raise ValueError("generation evidence text disagrees with its schedule")
|
| 1688 |
+
text_variants = candidate_generation_text_variants(
|
| 1689 |
+
canonical_chunks,
|
| 1690 |
+
generation_context,
|
| 1691 |
+
)
|
| 1692 |
rows = tuple(
|
| 1693 |
chunk_cfg_evidence(
|
| 1694 |
chunk,
|
|
|
|
| 1711 |
floor_reasons=tuple(row[1] for row in rows),
|
| 1712 |
chunk_candidate_ordinals=candidate_ordinals,
|
| 1713 |
network_conditioned=network_flags,
|
| 1714 |
+
chunk_text_variants=text_variants,
|
| 1715 |
)
|
| 1716 |
|
| 1717 |
try:
|
quality_runtime.py
CHANGED
|
@@ -61,7 +61,7 @@ RELEASE_SPEAKER_TRIGGER_SECONDS = 1.48
|
|
| 61 |
SEQUENCE_FALLBACK_MAX_LOCAL_BOUNDARY_SPEAKER_DROP = 0.15
|
| 62 |
SEQUENCE_FALLBACK_SPEAKER_WEIGHT = 0.05
|
| 63 |
SEQUENCE_FALLBACK_BOUNDARY_WEIGHT = 0.10
|
| 64 |
-
CASCADE_EVIDENCE_SCHEMA_VERSION =
|
| 65 |
CASCADE_EVIDENCE_LOG_PREFIX = "[BlueMagpie] cascade evidence "
|
| 66 |
CASCADE_EVIDENCE_MAX_ATTEMPTS = ADAPTIVE_CASCADE_STAGE_LIMITS[-1]
|
| 67 |
CASCADE_EVIDENCE_MAX_LOCAL_RESULTS = ADAPTIVE_CASCADE_STAGE_LIMITS[-1]
|
|
@@ -1583,6 +1583,7 @@ class CandidateGenerationEvidence:
|
|
| 1583 |
floor_reasons: tuple[tuple[str, ...], ...]
|
| 1584 |
chunk_candidate_ordinals: tuple[int, ...] = ()
|
| 1585 |
network_conditioned: tuple[bool, ...] = ()
|
|
|
|
| 1586 |
|
| 1587 |
|
| 1588 |
@dataclass(frozen=True)
|
|
@@ -1600,6 +1601,7 @@ class CandidateAttemptEvidence:
|
|
| 1600 |
chunk_text_units: tuple[int, ...]
|
| 1601 |
chunk_candidate_ordinals: tuple[int, ...]
|
| 1602 |
network_conditioned: tuple[bool, ...]
|
|
|
|
| 1603 |
scheduled_cfg: float | None
|
| 1604 |
effective_cfgs: tuple[float, ...]
|
| 1605 |
floor_reasons: tuple[tuple[str, ...], ...]
|
|
@@ -2526,6 +2528,7 @@ def _candidate_attempt_evidence_payload(
|
|
| 2526 |
"chunk_text_units": list(evidence.chunk_text_units),
|
| 2527 |
"chunk_candidate_ordinals": list(candidate_ordinals),
|
| 2528 |
"chunk_policies": chunk_policies,
|
|
|
|
| 2529 |
"network_conditioned": list(evidence.network_conditioned),
|
| 2530 |
"scheduled_cfg": evidence.scheduled_cfg,
|
| 2531 |
"effective_cfgs": list(evidence.effective_cfgs),
|
|
@@ -2615,6 +2618,7 @@ def _selected_generation_evidence_payload(
|
|
| 2615 |
candidate_ordinals: list[int | None] = []
|
| 2616 |
policies: list[str | None] = []
|
| 2617 |
network_conditioned: list[bool | None] = []
|
|
|
|
| 2618 |
complete = True
|
| 2619 |
for chunk_index, candidate_index in enumerate(
|
| 2620 |
selection.chunk_candidate_indices
|
|
@@ -2628,6 +2632,7 @@ def _selected_generation_evidence_payload(
|
|
| 2628 |
candidate_ordinals.append(None)
|
| 2629 |
policies.append(None)
|
| 2630 |
network_conditioned.append(None)
|
|
|
|
| 2631 |
continue
|
| 2632 |
try:
|
| 2633 |
local_index = attempt.chunk_indices.index(chunk_index)
|
|
@@ -2641,6 +2646,7 @@ def _selected_generation_evidence_payload(
|
|
| 2641 |
candidate_ordinals.append(None)
|
| 2642 |
policies.append(None)
|
| 2643 |
network_conditioned.append(None)
|
|
|
|
| 2644 |
continue
|
| 2645 |
try:
|
| 2646 |
ordinal = attempt.chunk_candidate_ordinals[local_index]
|
|
@@ -2661,6 +2667,11 @@ def _selected_generation_evidence_payload(
|
|
| 2661 |
except IndexError:
|
| 2662 |
complete = False
|
| 2663 |
network_conditioned.append(None)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2664 |
return {
|
| 2665 |
"complete": complete,
|
| 2666 |
"chunk_scheduled_cfgs": scheduled_cfgs,
|
|
@@ -2669,6 +2680,7 @@ def _selected_generation_evidence_payload(
|
|
| 2669 |
"chunk_candidate_ordinals": candidate_ordinals,
|
| 2670 |
"chunk_policies": policies,
|
| 2671 |
"network_conditioned": network_conditioned,
|
|
|
|
| 2672 |
}
|
| 2673 |
|
| 2674 |
|
|
@@ -2753,6 +2765,7 @@ def format_cascade_evidence_log(
|
|
| 2753 |
and len(attempt.chunk_indices) == len(attempt.chunk_text_units)
|
| 2754 |
== len(attempt.chunk_candidate_ordinals)
|
| 2755 |
== len(attempt.network_conditioned)
|
|
|
|
| 2756 |
== len(attempt.effective_cfgs)
|
| 2757 |
== len(attempt.floor_reasons)
|
| 2758 |
and bool(attempt.chunk_indices)
|
|
@@ -3298,6 +3311,21 @@ def _validated_candidate_generation_evidence(
|
|
| 3298 |
network_conditioned = value.network_conditioned
|
| 3299 |
else:
|
| 3300 |
network_conditioned = (False,) * len(chunks)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3301 |
raw_ordinals = value.chunk_candidate_ordinals
|
| 3302 |
if not raw_ordinals:
|
| 3303 |
if require_explicit_candidate_ordinals:
|
|
@@ -3377,6 +3405,7 @@ def _validated_candidate_generation_evidence(
|
|
| 3377 |
floor_reasons=tuple(floor_reasons),
|
| 3378 |
chunk_candidate_ordinals=candidate_ordinals,
|
| 3379 |
network_conditioned=network_conditioned,
|
|
|
|
| 3380 |
)
|
| 3381 |
|
| 3382 |
|
|
@@ -3415,6 +3444,9 @@ def _candidate_attempt_evidence(
|
|
| 3415 |
network_conditioned=(
|
| 3416 |
generation.network_conditioned if generation is not None else ()
|
| 3417 |
),
|
|
|
|
|
|
|
|
|
|
| 3418 |
scheduled_cfg=(generation.scheduled_cfg if generation is not None else None),
|
| 3419 |
effective_cfgs=(generation.effective_cfgs if generation is not None else ()),
|
| 3420 |
floor_reasons=(generation.floor_reasons if generation is not None else ()),
|
|
|
|
| 61 |
SEQUENCE_FALLBACK_MAX_LOCAL_BOUNDARY_SPEAKER_DROP = 0.15
|
| 62 |
SEQUENCE_FALLBACK_SPEAKER_WEIGHT = 0.05
|
| 63 |
SEQUENCE_FALLBACK_BOUNDARY_WEIGHT = 0.10
|
| 64 |
+
CASCADE_EVIDENCE_SCHEMA_VERSION = 5
|
| 65 |
CASCADE_EVIDENCE_LOG_PREFIX = "[BlueMagpie] cascade evidence "
|
| 66 |
CASCADE_EVIDENCE_MAX_ATTEMPTS = ADAPTIVE_CASCADE_STAGE_LIMITS[-1]
|
| 67 |
CASCADE_EVIDENCE_MAX_LOCAL_RESULTS = ADAPTIVE_CASCADE_STAGE_LIMITS[-1]
|
|
|
|
| 1583 |
floor_reasons: tuple[tuple[str, ...], ...]
|
| 1584 |
chunk_candidate_ordinals: tuple[int, ...] = ()
|
| 1585 |
network_conditioned: tuple[bool, ...] = ()
|
| 1586 |
+
chunk_text_variants: tuple[str, ...] = ()
|
| 1587 |
|
| 1588 |
|
| 1589 |
@dataclass(frozen=True)
|
|
|
|
| 1601 |
chunk_text_units: tuple[int, ...]
|
| 1602 |
chunk_candidate_ordinals: tuple[int, ...]
|
| 1603 |
network_conditioned: tuple[bool, ...]
|
| 1604 |
+
chunk_text_variants: tuple[str, ...]
|
| 1605 |
scheduled_cfg: float | None
|
| 1606 |
effective_cfgs: tuple[float, ...]
|
| 1607 |
floor_reasons: tuple[tuple[str, ...], ...]
|
|
|
|
| 2528 |
"chunk_text_units": list(evidence.chunk_text_units),
|
| 2529 |
"chunk_candidate_ordinals": list(candidate_ordinals),
|
| 2530 |
"chunk_policies": chunk_policies,
|
| 2531 |
+
"chunk_text_variants": list(evidence.chunk_text_variants),
|
| 2532 |
"network_conditioned": list(evidence.network_conditioned),
|
| 2533 |
"scheduled_cfg": evidence.scheduled_cfg,
|
| 2534 |
"effective_cfgs": list(evidence.effective_cfgs),
|
|
|
|
| 2618 |
candidate_ordinals: list[int | None] = []
|
| 2619 |
policies: list[str | None] = []
|
| 2620 |
network_conditioned: list[bool | None] = []
|
| 2621 |
+
chunk_text_variants: list[str | None] = []
|
| 2622 |
complete = True
|
| 2623 |
for chunk_index, candidate_index in enumerate(
|
| 2624 |
selection.chunk_candidate_indices
|
|
|
|
| 2632 |
candidate_ordinals.append(None)
|
| 2633 |
policies.append(None)
|
| 2634 |
network_conditioned.append(None)
|
| 2635 |
+
chunk_text_variants.append(None)
|
| 2636 |
continue
|
| 2637 |
try:
|
| 2638 |
local_index = attempt.chunk_indices.index(chunk_index)
|
|
|
|
| 2646 |
candidate_ordinals.append(None)
|
| 2647 |
policies.append(None)
|
| 2648 |
network_conditioned.append(None)
|
| 2649 |
+
chunk_text_variants.append(None)
|
| 2650 |
continue
|
| 2651 |
try:
|
| 2652 |
ordinal = attempt.chunk_candidate_ordinals[local_index]
|
|
|
|
| 2667 |
except IndexError:
|
| 2668 |
complete = False
|
| 2669 |
network_conditioned.append(None)
|
| 2670 |
+
try:
|
| 2671 |
+
chunk_text_variants.append(attempt.chunk_text_variants[local_index])
|
| 2672 |
+
except IndexError:
|
| 2673 |
+
complete = False
|
| 2674 |
+
chunk_text_variants.append(None)
|
| 2675 |
return {
|
| 2676 |
"complete": complete,
|
| 2677 |
"chunk_scheduled_cfgs": scheduled_cfgs,
|
|
|
|
| 2680 |
"chunk_candidate_ordinals": candidate_ordinals,
|
| 2681 |
"chunk_policies": policies,
|
| 2682 |
"network_conditioned": network_conditioned,
|
| 2683 |
+
"chunk_text_variants": chunk_text_variants,
|
| 2684 |
}
|
| 2685 |
|
| 2686 |
|
|
|
|
| 2765 |
and len(attempt.chunk_indices) == len(attempt.chunk_text_units)
|
| 2766 |
== len(attempt.chunk_candidate_ordinals)
|
| 2767 |
== len(attempt.network_conditioned)
|
| 2768 |
+
== len(attempt.chunk_text_variants)
|
| 2769 |
== len(attempt.effective_cfgs)
|
| 2770 |
== len(attempt.floor_reasons)
|
| 2771 |
and bool(attempt.chunk_indices)
|
|
|
|
| 3311 |
network_conditioned = value.network_conditioned
|
| 3312 |
else:
|
| 3313 |
network_conditioned = (False,) * len(chunks)
|
| 3314 |
+
if value.chunk_text_variants:
|
| 3315 |
+
if (
|
| 3316 |
+
not isinstance(value.chunk_text_variants, tuple)
|
| 3317 |
+
or len(value.chunk_text_variants) != len(chunks)
|
| 3318 |
+
or any(
|
| 3319 |
+
variant not in {"base", "email_domain_mail_v1"}
|
| 3320 |
+
for variant in value.chunk_text_variants
|
| 3321 |
+
)
|
| 3322 |
+
):
|
| 3323 |
+
raise ValueError(
|
| 3324 |
+
"generation evidence text variants do not match the attempt"
|
| 3325 |
+
)
|
| 3326 |
+
chunk_text_variants = value.chunk_text_variants
|
| 3327 |
+
else:
|
| 3328 |
+
chunk_text_variants = ("base",) * len(chunks)
|
| 3329 |
raw_ordinals = value.chunk_candidate_ordinals
|
| 3330 |
if not raw_ordinals:
|
| 3331 |
if require_explicit_candidate_ordinals:
|
|
|
|
| 3405 |
floor_reasons=tuple(floor_reasons),
|
| 3406 |
chunk_candidate_ordinals=candidate_ordinals,
|
| 3407 |
network_conditioned=network_conditioned,
|
| 3408 |
+
chunk_text_variants=chunk_text_variants,
|
| 3409 |
)
|
| 3410 |
|
| 3411 |
|
|
|
|
| 3444 |
network_conditioned=(
|
| 3445 |
generation.network_conditioned if generation is not None else ()
|
| 3446 |
),
|
| 3447 |
+
chunk_text_variants=(
|
| 3448 |
+
generation.chunk_text_variants if generation is not None else ()
|
| 3449 |
+
),
|
| 3450 |
scheduled_cfg=(generation.scheduled_cfg if generation is not None else None),
|
| 3451 |
effective_cfgs=(generation.effective_cfgs if generation is not None else ()),
|
| 3452 |
floor_reasons=(generation.floor_reasons if generation is not None else ()),
|
tests/test_coverage_adaptive.py
CHANGED
|
@@ -567,7 +567,7 @@ def test_refill_budget_accounts_exact_generated_chunks_and_text_units():
|
|
| 567 |
selection=result,
|
| 568 |
)
|
| 569 |
payload = json.loads(line.removeprefix(CASCADE_EVIDENCE_LOG_PREFIX))
|
| 570 |
-
assert payload["schema_version"] ==
|
| 571 |
assert payload["generation_evidence_complete"] is True
|
| 572 |
assert payload["request_chunk_count"] == 2
|
| 573 |
assert payload["generated_chunk_count"] == 3
|
|
@@ -589,6 +589,7 @@ def test_refill_budget_accounts_exact_generated_chunks_and_text_units():
|
|
| 589 |
"chunk_candidate_ordinals": [1, 0],
|
| 590 |
"chunk_policies": ["safe_duration", "base"],
|
| 591 |
"network_conditioned": [False, False],
|
|
|
|
| 592 |
}
|
| 593 |
|
| 594 |
|
|
@@ -1221,6 +1222,91 @@ def test_remaining_budget_prioritizes_request_endpoints_after_full_coverage():
|
|
| 1221 |
assert result.chunk_candidate_counts == (1, 1, 2)
|
| 1222 |
|
| 1223 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1224 |
def test_ragged_dp_accepts_unequal_row_widths_and_stable_cost_order():
|
| 1225 |
ranked = select_culprit_diverse_candidate_sequences(
|
| 1226 |
[[0.0], [0.3, 0.1, 0.2], [0.4, 0.0]],
|
|
|
|
| 567 |
selection=result,
|
| 568 |
)
|
| 569 |
payload = json.loads(line.removeprefix(CASCADE_EVIDENCE_LOG_PREFIX))
|
| 570 |
+
assert payload["schema_version"] == 5
|
| 571 |
assert payload["generation_evidence_complete"] is True
|
| 572 |
assert payload["request_chunk_count"] == 2
|
| 573 |
assert payload["generated_chunk_count"] == 3
|
|
|
|
| 589 |
"chunk_candidate_ordinals": [1, 0],
|
| 590 |
"chunk_policies": ["safe_duration", "base"],
|
| 591 |
"network_conditioned": [False, False],
|
| 592 |
+
"chunk_text_variants": ["base", "base"],
|
| 593 |
}
|
| 594 |
|
| 595 |
|
|
|
|
| 1222 |
assert result.chunk_candidate_counts == (1, 1, 2)
|
| 1223 |
|
| 1224 |
|
| 1225 |
+
def test_exact_asr_speaker_near_miss_gets_priority_then_latest_result_reorders():
|
| 1226 |
+
chunks = ("第一段", "第二段")
|
| 1227 |
+
generated = []
|
| 1228 |
+
|
| 1229 |
+
def verification(candidate_chunks, states):
|
| 1230 |
+
observations = []
|
| 1231 |
+
artifacts = []
|
| 1232 |
+
for chunk, state in zip(candidate_chunks, states, strict=True):
|
| 1233 |
+
semantic_passed = state != "semantic_failure"
|
| 1234 |
+
speaker_similarity = 0.05 if state == "speaker_near_miss" else 0.80
|
| 1235 |
+
observations.append(
|
| 1236 |
+
CandidateObservation(
|
| 1237 |
+
target_text=chunk,
|
| 1238 |
+
transcript_text=chunk if semantic_passed else "完全錯誤",
|
| 1239 |
+
audio_duration_seconds=2.0,
|
| 1240 |
+
speaker_similarity=speaker_similarity,
|
| 1241 |
+
begin_speaker_similarity=speaker_similarity,
|
| 1242 |
+
end_speaker_similarity=speaker_similarity,
|
| 1243 |
+
pace_cps=2.0,
|
| 1244 |
+
)
|
| 1245 |
+
)
|
| 1246 |
+
artifacts.append(
|
| 1247 |
+
ChunkCandidateArtifact(
|
| 1248 |
+
speaker_embedding=np.array([1.0, 0.0], dtype=np.float32),
|
| 1249 |
+
rms_db=-20.0,
|
| 1250 |
+
)
|
| 1251 |
+
)
|
| 1252 |
+
return verify_trajectory(
|
| 1253 |
+
observations,
|
| 1254 |
+
chunk_artifacts=artifacts,
|
| 1255 |
+
max_pace_cps=4.3,
|
| 1256 |
+
min_speaker_similarity=0.10,
|
| 1257 |
+
)
|
| 1258 |
+
|
| 1259 |
+
initial_local = verification(
|
| 1260 |
+
chunks,
|
| 1261 |
+
("semantic_failure", "speaker_near_miss"),
|
| 1262 |
+
)
|
| 1263 |
+
assert initial_local.candidate_results[0].comparison.passed is False
|
| 1264 |
+
assert initial_local.candidate_results[1].comparison.passed is True
|
| 1265 |
+
assert "speaker_similarity" in initial_local.candidate_results[
|
| 1266 |
+
1
|
| 1267 |
+
].rejection_reasons
|
| 1268 |
+
|
| 1269 |
+
def generator(candidate_chunks, seed):
|
| 1270 |
+
generated.append((candidate_chunks, seed))
|
| 1271 |
+
return tuple(f"{seed}:{chunk}" for chunk in candidate_chunks)
|
| 1272 |
+
|
| 1273 |
+
def refill_verifier(trajectory, candidate_chunks, seed):
|
| 1274 |
+
state = (
|
| 1275 |
+
"semantic_failure"
|
| 1276 |
+
if candidate_chunks == ("第二段",) and seed == 101
|
| 1277 |
+
else "passed"
|
| 1278 |
+
)
|
| 1279 |
+
return verification(candidate_chunks, (state,))
|
| 1280 |
+
|
| 1281 |
+
result = run_coverage_adaptive_cascade(
|
| 1282 |
+
chunks,
|
| 1283 |
+
100,
|
| 1284 |
+
generator,
|
| 1285 |
+
lambda trajectory, candidate_chunks, seed: TrajectoryGateResult(
|
| 1286 |
+
passed=False,
|
| 1287 |
+
candidate_results=initial_local.candidate_results,
|
| 1288 |
+
score=math.inf,
|
| 1289 |
+
rejection_reasons=("joined_output:semantic_gate",),
|
| 1290 |
+
chunk_artifacts=initial_local.chunk_artifacts,
|
| 1291 |
+
),
|
| 1292 |
+
refill_verifier,
|
| 1293 |
+
sequence_final_verifier=lambda result, candidate_chunks: _exact_final(
|
| 1294 |
+
candidate_chunks
|
| 1295 |
+
),
|
| 1296 |
+
max_generated_chunks=5,
|
| 1297 |
+
max_generated_text_units=100,
|
| 1298 |
+
max_sequence_paths=1,
|
| 1299 |
+
)
|
| 1300 |
+
|
| 1301 |
+
assert generated[1:] == [
|
| 1302 |
+
(("第二段",), 101),
|
| 1303 |
+
(("第一段",), 102),
|
| 1304 |
+
(("第二段",), 103),
|
| 1305 |
+
]
|
| 1306 |
+
assert result.chunk_candidate_indices == (2, 3)
|
| 1307 |
+
assert result.chunk_candidate_counts == (1, 1)
|
| 1308 |
+
|
| 1309 |
+
|
| 1310 |
def test_ragged_dp_accepts_unequal_row_widths_and_stable_cost_order():
|
| 1311 |
ranked = select_culprit_diverse_candidate_sequences(
|
| 1312 |
[[0.0], [0.3, 0.1, 0.2], [0.4, 0.0]],
|
tests/test_production.py
CHANGED
|
@@ -1054,6 +1054,37 @@ def test_network_request_bounded_ordinary_envelope_splits_long_final_clause():
|
|
| 1054 |
assert "".join(spec.text for spec in specs) == target
|
| 1055 |
|
| 1056 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1057 |
def test_generation_network_planner_prefers_context_before_identifier_start():
|
| 1058 |
raw = (
|
| 1059 |
"途中若發現落石或樹枝阻斷通行,請拍照並寄到 "
|
|
|
|
| 1054 |
assert "".join(spec.text for spec in specs) == target
|
| 1055 |
|
| 1056 |
|
| 1057 |
+
@pytest.mark.parametrize(
|
| 1058 |
+
("terminal_units", "expected_units"),
|
| 1059 |
+
(
|
| 1060 |
+
(36, (14, 36)),
|
| 1061 |
+
(37, (14, 25, 12)),
|
| 1062 |
+
),
|
| 1063 |
+
)
|
| 1064 |
+
def test_network_request_terminal_ordinary_clause_splits_only_above_36_units(
|
| 1065 |
+
terminal_units,
|
| 1066 |
+
expected_units,
|
| 1067 |
+
):
|
| 1068 |
+
raw = "請寄到 patrol@forestmail.tw。" + "甲" * terminal_units + "。"
|
| 1069 |
+
target = normalize_spoken_forms(raw)
|
| 1070 |
+
|
| 1071 |
+
specs = plan_generation_chunks(raw, target, ordinary_max_units=36)
|
| 1072 |
+
|
| 1073 |
+
assert tuple(count_speech_units(spec.text) for spec in specs) == expected_units
|
| 1074 |
+
assert specs[0].network_conditioned
|
| 1075 |
+
assert all(not spec.network_conditioned for spec in specs[1:])
|
| 1076 |
+
assert all(
|
| 1077 |
+
left.source_end == right.source_start
|
| 1078 |
+
for left, right in zip(specs, specs[1:], strict=False)
|
| 1079 |
+
)
|
| 1080 |
+
assert specs[0].source_start == 0
|
| 1081 |
+
assert specs[-1].source_end == len(target)
|
| 1082 |
+
assert all(spec.boundary_after == "semantic" for spec in specs[:-1])
|
| 1083 |
+
assert specs[-1].boundary_after == "none"
|
| 1084 |
+
assert max(count_speech_units(spec.text) for spec in specs) <= 36
|
| 1085 |
+
assert "".join(spec.text for spec in specs) == target
|
| 1086 |
+
|
| 1087 |
+
|
| 1088 |
def test_generation_network_planner_prefers_context_before_identifier_start():
|
| 1089 |
raw = (
|
| 1090 |
"途中若發現落石或樹枝阻斷通行,請拍照並寄到 "
|
tests/test_quality_runtime.py
CHANGED
|
@@ -1675,7 +1675,7 @@ def test_canonical_attempt_evidence_distinguishes_local_v3_pass_and_not_run():
|
|
| 1675 |
)
|
| 1676 |
attempt = payload["attempts"][0]
|
| 1677 |
|
| 1678 |
-
assert payload["schema_version"] ==
|
| 1679 |
assert attempt["independent_local_evidence_complete"] is True
|
| 1680 |
assert attempt["independent_local_results"] == [
|
| 1681 |
{
|
|
|
|
| 1675 |
)
|
| 1676 |
attempt = payload["attempts"][0]
|
| 1677 |
|
| 1678 |
+
assert payload["schema_version"] == 5
|
| 1679 |
assert attempt["independent_local_evidence_complete"] is True
|
| 1680 |
assert attempt["independent_local_results"] == [
|
| 1681 |
{
|
tests/test_release_pins.py
CHANGED
|
@@ -3,6 +3,16 @@ import hashlib
|
|
| 3 |
from pathlib import Path
|
| 4 |
from types import SimpleNamespace
|
| 5 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
from quality_runtime import LocalIndependentGateEvidence
|
| 7 |
|
| 8 |
|
|
@@ -51,6 +61,59 @@ def _literal_constants(path: Path) -> dict[str, object]:
|
|
| 51 |
return values
|
| 52 |
|
| 53 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
def _isolated_load_speakers(*, metadata: dict, speaker_ids: tuple[str, ...]):
|
| 55 |
"""Execute only ``_load_speakers`` without importing the GPU application."""
|
| 56 |
|
|
@@ -522,7 +585,8 @@ def test_network_local_dual_asr_capability_is_range_bound_for_initial_and_refill
|
|
| 522 |
assert "chunk_artifacts=primary_verification.chunk_artifacts" in (
|
| 523 |
intersection_source
|
| 524 |
)
|
| 525 |
-
assert "CASCADE_EVIDENCE_SCHEMA_VERSION =
|
|
|
|
| 526 |
assert "local_candidate_has_coverage_eligibility(" in helper_source
|
| 527 |
assert "independent_local_results=" in initial_source
|
| 528 |
assert "independent_local_results=" in refill_source
|
|
@@ -1023,8 +1087,19 @@ def test_space_hard_intersects_dual_asr_on_whole_and_proven_network_locals():
|
|
| 1023 |
sequence_large_v3_transcriber = sequence_source.index(
|
| 1024 |
"transcriber=transcribe_verification_whisper"
|
| 1025 |
)
|
| 1026 |
-
|
| 1027 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1028 |
|
| 1029 |
cache_create = synthesize_source.index(
|
| 1030 |
"independent_cache = WholeWaveformVerificationCache()"
|
|
@@ -1306,6 +1381,88 @@ def test_space_locks_validated_nfe_and_bounds_total_generation_work():
|
|
| 1306 |
assert "boundary-only relaxation" in readme
|
| 1307 |
|
| 1308 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1309 |
def test_space_locks_waveform_only_bounded_whisper_segmentation():
|
| 1310 |
source = (ROOT / "quality_runtime.py").read_text(encoding="utf-8")
|
| 1311 |
readme = (ROOT / "README.md").read_text(encoding="utf-8")
|
|
|
|
| 3 |
from pathlib import Path
|
| 4 |
from types import SimpleNamespace
|
| 5 |
|
| 6 |
+
import numpy as np
|
| 7 |
+
|
| 8 |
+
from production import (
|
| 9 |
+
GenerationChunkSpec,
|
| 10 |
+
count_speech_units,
|
| 11 |
+
fade_variable_internal_edges,
|
| 12 |
+
join_audio_chunks_variable,
|
| 13 |
+
match_chunk_rms,
|
| 14 |
+
punctuation_pause_seconds,
|
| 15 |
+
)
|
| 16 |
from quality_runtime import LocalIndependentGateEvidence
|
| 17 |
|
| 18 |
|
|
|
|
| 61 |
return values
|
| 62 |
|
| 63 |
|
| 64 |
+
def _isolated_assemble_trajectory_audio():
|
| 65 |
+
"""Execute only the production assembly function without loading the model."""
|
| 66 |
+
|
| 67 |
+
app_path = ROOT / "app.py"
|
| 68 |
+
tree = ast.parse(app_path.read_text(encoding="utf-8"))
|
| 69 |
+
function = next(
|
| 70 |
+
node
|
| 71 |
+
for node in tree.body
|
| 72 |
+
if isinstance(node, ast.FunctionDef)
|
| 73 |
+
and node.name == "_assemble_trajectory_audio"
|
| 74 |
+
)
|
| 75 |
+
module = ast.Module(
|
| 76 |
+
body=[
|
| 77 |
+
ast.ImportFrom(
|
| 78 |
+
module="__future__",
|
| 79 |
+
names=[ast.alias(name="annotations")],
|
| 80 |
+
level=0,
|
| 81 |
+
),
|
| 82 |
+
function,
|
| 83 |
+
],
|
| 84 |
+
type_ignores=[],
|
| 85 |
+
)
|
| 86 |
+
ast.fix_missing_locations(module)
|
| 87 |
+
|
| 88 |
+
constants = _literal_constants(app_path)
|
| 89 |
+
namespace = {
|
| 90 |
+
"np": np,
|
| 91 |
+
"GenerationChunkSpec": GenerationChunkSpec,
|
| 92 |
+
"SR": 1_000,
|
| 93 |
+
"CHUNK_RMS_MATCH_DB": constants["CHUNK_RMS_MATCH_DB"],
|
| 94 |
+
"SEMANTIC_CHUNK_MIN_SILENCE_MS": constants[
|
| 95 |
+
"SEMANTIC_CHUNK_MIN_SILENCE_MS"
|
| 96 |
+
],
|
| 97 |
+
"NETWORK_REQUEST_SEMANTIC_CHUNK_MIN_SILENCE_MS": constants[
|
| 98 |
+
"NETWORK_REQUEST_SEMANTIC_CHUNK_MIN_SILENCE_MS"
|
| 99 |
+
],
|
| 100 |
+
"NETWORK_INTERNAL_SILENCE_MS": constants["NETWORK_INTERNAL_SILENCE_MS"],
|
| 101 |
+
"NETWORK_INTERNAL_FADE_MS": constants["NETWORK_INTERNAL_FADE_MS"],
|
| 102 |
+
"CHUNK_EDGE_FADE_MS": constants["CHUNK_EDGE_FADE_MS"],
|
| 103 |
+
"CROSSFADE_MS": constants["CROSSFADE_MS"],
|
| 104 |
+
"match_chunk_rms": match_chunk_rms,
|
| 105 |
+
"punctuation_pause_seconds": punctuation_pause_seconds,
|
| 106 |
+
"fade_variable_internal_edges": fade_variable_internal_edges,
|
| 107 |
+
"join_audio_chunks_variable": join_audio_chunks_variable,
|
| 108 |
+
"apply_loudness_floor": lambda waveform, **_kwargs: waveform,
|
| 109 |
+
"_apply_speed": lambda waveform, _speed: waveform,
|
| 110 |
+
"count_speech_units": count_speech_units,
|
| 111 |
+
"finish_audio": lambda waveform, _sample_rate, **_kwargs: waveform,
|
| 112 |
+
}
|
| 113 |
+
exec(compile(module, str(app_path), "exec"), namespace)
|
| 114 |
+
return namespace["_assemble_trajectory_audio"]
|
| 115 |
+
|
| 116 |
+
|
| 117 |
def _isolated_load_speakers(*, metadata: dict, speaker_ids: tuple[str, ...]):
|
| 118 |
"""Execute only ``_load_speakers`` without importing the GPU application."""
|
| 119 |
|
|
|
|
| 585 |
assert "chunk_artifacts=primary_verification.chunk_artifacts" in (
|
| 586 |
intersection_source
|
| 587 |
)
|
| 588 |
+
assert "CASCADE_EVIDENCE_SCHEMA_VERSION = 5" in quality_source
|
| 589 |
+
assert '"chunk_text_variants"' in quality_source
|
| 590 |
assert "local_candidate_has_coverage_eligibility(" in helper_source
|
| 591 |
assert "independent_local_results=" in initial_source
|
| 592 |
assert "independent_local_results=" in refill_source
|
|
|
|
| 1087 |
sequence_large_v3_transcriber = sequence_source.index(
|
| 1088 |
"transcriber=transcribe_verification_whisper"
|
| 1089 |
)
|
| 1090 |
+
sequence_independent = sequence_source.index(
|
| 1091 |
+
"independent_verification = _verify_independent_whole_audio("
|
| 1092 |
+
)
|
| 1093 |
+
sequence_intersection = sequence_source.index(
|
| 1094 |
+
"intersected = qualify_trajectory_with_joined_output("
|
| 1095 |
+
)
|
| 1096 |
+
assert (
|
| 1097 |
+
sequence_assemble
|
| 1098 |
+
< sequence_large_v3
|
| 1099 |
+
< sequence_large_v3_transcriber
|
| 1100 |
+
< sequence_independent
|
| 1101 |
+
< sequence_intersection
|
| 1102 |
+
)
|
| 1103 |
|
| 1104 |
cache_create = synthesize_source.index(
|
| 1105 |
"independent_cache = WholeWaveformVerificationCache()"
|
|
|
|
| 1381 |
assert "boundary-only relaxation" in readme
|
| 1382 |
|
| 1383 |
|
| 1384 |
+
def test_pace_only_fallback_guard_starts_at_30_ordinary_units_not_29():
|
| 1385 |
+
app_path = ROOT / "app.py"
|
| 1386 |
+
constants = _literal_constants(app_path)
|
| 1387 |
+
tree = ast.parse(app_path.read_text(encoding="utf-8"))
|
| 1388 |
+
generate_chunk = next(
|
| 1389 |
+
node
|
| 1390 |
+
for node in tree.body
|
| 1391 |
+
if isinstance(node, ast.FunctionDef) and node.name == "_generate_chunk"
|
| 1392 |
+
)
|
| 1393 |
+
guarded_ifs = [
|
| 1394 |
+
node
|
| 1395 |
+
for node in ast.walk(generate_chunk)
|
| 1396 |
+
if isinstance(node, ast.If)
|
| 1397 |
+
and any(
|
| 1398 |
+
isinstance(name, ast.Name)
|
| 1399 |
+
and name.id == "PACE_ONLY_FALLBACK_MIN_UNITS"
|
| 1400 |
+
for name in ast.walk(node.test)
|
| 1401 |
+
)
|
| 1402 |
+
]
|
| 1403 |
+
|
| 1404 |
+
assert constants["PACE_ONLY_FALLBACK_MIN_UNITS"] == 30
|
| 1405 |
+
assert len(guarded_ifs) == 1
|
| 1406 |
+
expression = ast.Expression(body=guarded_ifs[0].test)
|
| 1407 |
+
ast.fix_missing_locations(expression)
|
| 1408 |
+
guard = compile(expression, str(app_path), "eval")
|
| 1409 |
+
|
| 1410 |
+
def eligible(units, *, network_conditioned=False):
|
| 1411 |
+
return eval(
|
| 1412 |
+
guard,
|
| 1413 |
+
{
|
| 1414 |
+
"PACE_ONLY_FALLBACK_MIN_UNITS": constants[
|
| 1415 |
+
"PACE_ONLY_FALLBACK_MIN_UNITS"
|
| 1416 |
+
],
|
| 1417 |
+
"count_speech_units": lambda _text: units,
|
| 1418 |
+
"network_conditioned": network_conditioned,
|
| 1419 |
+
"text": "測試",
|
| 1420 |
+
},
|
| 1421 |
+
)
|
| 1422 |
+
|
| 1423 |
+
assert eligible(29) is False
|
| 1424 |
+
assert eligible(30) is True
|
| 1425 |
+
assert eligible(30, network_conditioned=True) is False
|
| 1426 |
+
|
| 1427 |
+
|
| 1428 |
+
def test_assembled_waveform_uses_250ms_ordinary_and_350ms_network_request_pause():
|
| 1429 |
+
assemble = _isolated_assemble_trajectory_audio()
|
| 1430 |
+
chunks = ("第一段,", "第二段")
|
| 1431 |
+
trajectory = (
|
| 1432 |
+
np.ones(100, dtype=np.float32),
|
| 1433 |
+
np.ones(100, dtype=np.float32),
|
| 1434 |
+
)
|
| 1435 |
+
|
| 1436 |
+
ordinary = assemble(trajectory, chunks, 1.0)
|
| 1437 |
+
|
| 1438 |
+
assert ordinary.shape == (450,)
|
| 1439 |
+
np.testing.assert_array_equal(ordinary[100:350], np.zeros(250, dtype=np.float32))
|
| 1440 |
+
|
| 1441 |
+
first_end = len(chunks[0])
|
| 1442 |
+
network_specs = (
|
| 1443 |
+
GenerationChunkSpec(
|
| 1444 |
+
text=chunks[0],
|
| 1445 |
+
source_start=0,
|
| 1446 |
+
source_end=first_end,
|
| 1447 |
+
boundary_after="semantic",
|
| 1448 |
+
),
|
| 1449 |
+
GenerationChunkSpec(
|
| 1450 |
+
text=chunks[1],
|
| 1451 |
+
source_start=first_end,
|
| 1452 |
+
source_end=first_end + len(chunks[1]),
|
| 1453 |
+
network_span_indices=(0,),
|
| 1454 |
+
boundary_after="none",
|
| 1455 |
+
),
|
| 1456 |
+
)
|
| 1457 |
+
network_request = assemble(trajectory, chunks, 1.0, network_specs)
|
| 1458 |
+
|
| 1459 |
+
assert network_request.shape == (550,)
|
| 1460 |
+
np.testing.assert_array_equal(
|
| 1461 |
+
network_request[100:450],
|
| 1462 |
+
np.zeros(350, dtype=np.float32),
|
| 1463 |
+
)
|
| 1464 |
+
|
| 1465 |
+
|
| 1466 |
def test_space_locks_waveform_only_bounded_whisper_segmentation():
|
| 1467 |
source = (ROOT / "quality_runtime.py").read_text(encoding="utf-8")
|
| 1468 |
readme = (ROOT / "README.md").read_text(encoding="utf-8")
|