batchalign 0.8.2.post1__tar.gz → 0.8.2.post3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {batchalign-0.8.2.post1/batchalign.egg-info → batchalign-0.8.2.post3}/PKG-INFO +1 -1
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/cli/cli.py +5 -4
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/cli/dispatch.py +6 -2
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/formats/chat/generator.py +3 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/analysis/compare.py +166 -63
- batchalign-0.8.2.post3/batchalign/version +3 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3/batchalign.egg-info}/PKG-INFO +1 -1
- batchalign-0.8.2.post1/batchalign/version +0 -3
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/LICENSE +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/MANIFEST.in +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/README.md +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/__main__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/cli/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/cli/bench.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/cli/cache.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/constants.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/document.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/errors.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/formats/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/formats/base.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/formats/chat/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/formats/chat/file.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/formats/chat/lexer.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/formats/chat/parser.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/formats/chat/utils.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/formats/textgrid/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/formats/textgrid/file.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/formats/textgrid/generator.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/formats/textgrid/parser.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/audio_io.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/resolve.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/speaker/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/speaker/config.yaml +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/speaker/infer.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/speaker/utils.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/training/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/training/run.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/training/utils.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/utils.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/utterance/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/utterance/cantonese_infer.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/utterance/dataset.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/utterance/execute.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/utterance/infer.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/utterance/prep.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/utterance/train.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/wave2vec/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/wave2vec/infer_fa.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/whisper/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/whisper/infer_asr.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/whisper/infer_fa.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/analysis/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/analysis/eval.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/asr/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/asr/num2chinese.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/asr/num2lang/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/asr/num2lang/deu.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/asr/num2lang/ell.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/asr/num2lang/eng.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/asr/num2lang/eus.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/asr/num2lang/fra.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/asr/num2lang/hrv.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/asr/num2lang/ind.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/asr/num2lang/jpn.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/asr/num2lang/nld.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/asr/num2lang/por.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/asr/num2lang/spa.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/asr/num2lang/tha.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/asr/oai_whisper.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/asr/rev.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/asr/utils.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/asr/whisper.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/asr/whisperx.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/avqi/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/avqi/engine.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/base.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/cache.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/cleanup/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/cleanup/cleanup.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/cleanup/disfluencies.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/cleanup/parse_support.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/cleanup/retrace.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/cleanup/support/filled_pauses.eng +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/cleanup/support/replacements.eng +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/cleanup/support/test.test +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/diarization/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/diarization/pyannote.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/dispatch.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/fa/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/fa/wave2vec_fa.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/fa/whisper_fa.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/morphosyntax/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/morphosyntax/coref.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/morphosyntax/en/irr.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/morphosyntax/fr/apm.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/morphosyntax/fr/apmn.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/morphosyntax/fr/case.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/morphosyntax/ja/verbforms.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/morphosyntax/ud.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/opensmile/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/opensmile/engine.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/pipeline.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/speaker/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/speaker/nemo_speaker.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/translate/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/translate/gtrans.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/translate/seamless.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/translate/utils.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/utr/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/utr/rev_utr.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/utr/utils.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/utr/whisper_utr.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/utterance/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/utterance/ud_utterance.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/cli/test_dispatch_memory.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/conftest.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/formats/chat/test_chat_file.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/formats/chat/test_chat_generator.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/formats/chat/test_chat_lexer.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/formats/chat/test_chat_parser.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/formats/chat/test_chat_utils.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/formats/textgrid/test_textgrid.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/models/test_audio_io.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/models/test_audio_lazy.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/pipelines/analysis/test_eval.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/pipelines/asr/test_asr_pipeline.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/pipelines/asr/test_asr_utils.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/pipelines/cache/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/pipelines/cache/test_cache.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/pipelines/cleanup/test_disfluency.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/pipelines/cleanup/test_parse_support.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/pipelines/fa/test_fa_pipeline.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/pipelines/fa/test_fa_short_segments.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/pipelines/fixures.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/pipelines/test_pipeline.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/pipelines/test_pipeline_models.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/test_document.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/utils/__init__.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/utils/abbrev.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/utils/compounds.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/utils/config.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/utils/device.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/utils/dp.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/utils/names.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/utils/utils.py +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign.egg-info/SOURCES.txt +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign.egg-info/dependency_links.txt +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign.egg-info/entry_points.txt +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign.egg-info/requires.txt +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign.egg-info/top_level.txt +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/setup.cfg +0 -0
- {batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/setup.py +0 -0
|
@@ -415,10 +415,11 @@ def benchmark(ctx, in_dir, out_dir, lang, num_speakers, whisper, whisper_oai, **
|
|
|
415
415
|
def compare(ctx, in_dir, out_dir, lang, **kwargs):
|
|
416
416
|
"""Compare transcripts against gold-standard references.
|
|
417
417
|
|
|
418
|
-
For each FILE.cha in IN_DIR,
|
|
419
|
-
same directory.
|
|
420
|
-
|
|
421
|
-
|
|
418
|
+
For each FILE.cha in IN_DIR, looks for a companion FILE.gold.cha in the
|
|
419
|
+
same directory. If not found, falls back to template.gold.cha as the
|
|
420
|
+
default gold for all files. Runs morphosyntax analysis on the main
|
|
421
|
+
transcript, then produces a word-level diff stored as %%xsrep / %%xsmor
|
|
422
|
+
tiers and writes error metrics to a .compare.csv file in OUT_DIR.
|
|
422
423
|
"""
|
|
423
424
|
|
|
424
425
|
_dispatch("compare", lang, 1, ["cha"], ctx,
|
|
@@ -204,13 +204,17 @@ def _run_pipeline_for_file(command, pipeline, file, output, loader_info, writer_
|
|
|
204
204
|
if file.endswith(".gold.cha"):
|
|
205
205
|
return
|
|
206
206
|
|
|
207
|
-
# Find companion gold file
|
|
207
|
+
# Find companion gold file: FILE.gold.cha overrides, then
|
|
208
|
+
# template.gold.cha serves as the default for the whole directory
|
|
208
209
|
p = P(file)
|
|
209
210
|
gold_path = p.parent / (p.stem + ".gold.cha")
|
|
211
|
+
if not gold_path.exists():
|
|
212
|
+
gold_path = p.parent / "template.gold.cha"
|
|
210
213
|
if not gold_path.exists():
|
|
211
214
|
raise FileNotFoundError(
|
|
212
215
|
f"No gold .cha file found for comparison. "
|
|
213
|
-
f"main: {p.name}, expected: {
|
|
216
|
+
f"main: {p.name}, expected: {p.stem}.gold.cha or template.gold.cha, "
|
|
217
|
+
f"looked in: {str(p.parent)}"
|
|
214
218
|
)
|
|
215
219
|
|
|
216
220
|
main_doc = CHATFile(path=str(p)).doc
|
|
@@ -131,6 +131,9 @@ def generate_chat_utterance(utterance: Utterance, special_mor=False, write_wor=T
|
|
|
131
131
|
prefix = "+" if tok.status == "extra_main" else ("-" if tok.status == "extra_gold" else "")
|
|
132
132
|
xsrep_parts.append(f"{prefix}{tok.text}")
|
|
133
133
|
xsmor_parts.append(f"{prefix}{tok.pos or '?'}")
|
|
134
|
+
# Strip PUNCT POS from final element, keep the delimiter char (same as %mor)
|
|
135
|
+
if xsmor_parts and xsrep_parts and xsmor_parts[-1] == "PUNCT":
|
|
136
|
+
xsmor_parts[-1] = xsrep_parts[-1]
|
|
134
137
|
result.append(f"%xsrep:\t" + " ".join(xsrep_parts))
|
|
135
138
|
result.append(f"%xsmor:\t" + " ".join(xsmor_parts))
|
|
136
139
|
|
|
@@ -12,6 +12,7 @@ computes error-rate metrics for CSV output.
|
|
|
12
12
|
|
|
13
13
|
import re
|
|
14
14
|
import logging
|
|
15
|
+
from collections import Counter
|
|
15
16
|
from batchalign.document import *
|
|
16
17
|
from batchalign.pipelines.base import *
|
|
17
18
|
from batchalign.utils.dp import align, ExtraType, Extra, Match
|
|
@@ -151,6 +152,65 @@ def match_fn(x, y):
|
|
|
151
152
|
# --- End of eval.py duplicates ---
|
|
152
153
|
|
|
153
154
|
|
|
155
|
+
def _find_best_segment(gold_tokens, main_tokens, mfn):
|
|
156
|
+
"""Find a rough window using bag-of-words overlap.
|
|
157
|
+
|
|
158
|
+
The rough pass is order-invariant: it scores contiguous windows by token
|
|
159
|
+
multiset overlap with the gold utterance, ignoring order. To keep common
|
|
160
|
+
words from swallowing later transcript material, it only considers windows
|
|
161
|
+
near the gold utterance length. Among equally good windows it prefers the
|
|
162
|
+
latest one, not the earliest. The caller then runs the full Levenshtein
|
|
163
|
+
aligner inside that window to produce token annotations.
|
|
164
|
+
"""
|
|
165
|
+
if not gold_tokens or not main_tokens:
|
|
166
|
+
return 0, 0
|
|
167
|
+
|
|
168
|
+
gold_counts = Counter(gold_tokens)
|
|
169
|
+
gold_len = len(gold_tokens)
|
|
170
|
+
main_len = len(main_tokens)
|
|
171
|
+
|
|
172
|
+
min_window = max(1, gold_len - 2)
|
|
173
|
+
max_window = min(main_len, gold_len + 2)
|
|
174
|
+
|
|
175
|
+
best = (0, min(main_len, gold_len))
|
|
176
|
+
best_score = -1.0
|
|
177
|
+
best_len_delta = None
|
|
178
|
+
|
|
179
|
+
for span in range(min_window, max_window + 1):
|
|
180
|
+
window_counts = Counter(main_tokens[:span])
|
|
181
|
+
overlap = sum(min(window_counts[token], gold_counts[token]) for token in window_counts)
|
|
182
|
+
|
|
183
|
+
for start in range(0, main_len - span + 1):
|
|
184
|
+
if start > 0:
|
|
185
|
+
left = main_tokens[start - 1]
|
|
186
|
+
right = main_tokens[start + span - 1]
|
|
187
|
+
|
|
188
|
+
overlap -= min(window_counts[left], gold_counts[left])
|
|
189
|
+
window_counts[left] -= 1
|
|
190
|
+
overlap += min(window_counts[left], gold_counts[left])
|
|
191
|
+
|
|
192
|
+
overlap -= min(window_counts[right], gold_counts[right])
|
|
193
|
+
window_counts[right] += 1
|
|
194
|
+
overlap += min(window_counts[right], gold_counts[right])
|
|
195
|
+
|
|
196
|
+
score = overlap / gold_len
|
|
197
|
+
len_delta = abs(span - gold_len)
|
|
198
|
+
end = start + span
|
|
199
|
+
|
|
200
|
+
if score > best_score:
|
|
201
|
+
best = (start, end)
|
|
202
|
+
best_score = score
|
|
203
|
+
best_len_delta = len_delta
|
|
204
|
+
elif score == best_score:
|
|
205
|
+
if best_len_delta is None or len_delta < best_len_delta:
|
|
206
|
+
best = (start, end)
|
|
207
|
+
best_len_delta = len_delta
|
|
208
|
+
elif len_delta == best_len_delta and end > best[1]:
|
|
209
|
+
best = (start, end)
|
|
210
|
+
|
|
211
|
+
return best
|
|
212
|
+
|
|
213
|
+
|
|
154
214
|
def _get_pos(form):
|
|
155
215
|
"""Extract uppercased POS from a Form's morphology, or '?' if absent."""
|
|
156
216
|
if form is not None and form.morphology:
|
|
@@ -202,13 +262,10 @@ class CompareEngine(BatchalignEngine):
|
|
|
202
262
|
]
|
|
203
263
|
main_info = [] # (utt_idx, form_idx, Form)
|
|
204
264
|
main_words = []
|
|
205
|
-
main_punct = {} # utt_idx -> list of (form_idx, Form)
|
|
206
265
|
|
|
207
266
|
for utt_idx, utt in enumerate(main_utterances):
|
|
208
|
-
main_punct[utt_idx] = []
|
|
209
267
|
for form_idx, form in enumerate(utt.content):
|
|
210
268
|
if form.text.strip() in MOR_PUNCT + ENDING_PUNCT:
|
|
211
|
-
main_punct[utt_idx].append((form_idx, form))
|
|
212
269
|
continue
|
|
213
270
|
if form.text.strip().lower() in fillers:
|
|
214
271
|
continue
|
|
@@ -221,10 +278,13 @@ class CompareEngine(BatchalignEngine):
|
|
|
221
278
|
]
|
|
222
279
|
gold_info = [] # (utt_idx, form_idx, Form)
|
|
223
280
|
gold_words = []
|
|
281
|
+
gold_punct = {} # utt_idx -> list of (form_idx, Form)
|
|
224
282
|
|
|
225
283
|
for utt_idx, utt in enumerate(gold_utterances):
|
|
284
|
+
gold_punct[utt_idx] = []
|
|
226
285
|
for form_idx, form in enumerate(utt.content):
|
|
227
286
|
if form.text.strip() in MOR_PUNCT + ENDING_PUNCT:
|
|
287
|
+
gold_punct[utt_idx].append((form_idx, form))
|
|
228
288
|
continue
|
|
229
289
|
if form.text.strip().lower() in fillers:
|
|
230
290
|
continue
|
|
@@ -235,82 +295,125 @@ class CompareEngine(BatchalignEngine):
|
|
|
235
295
|
conformed_main, main_map = conform_with_mapping(main_words, conform)
|
|
236
296
|
conformed_gold, gold_map = conform_with_mapping(gold_words, conform)
|
|
237
297
|
|
|
238
|
-
# --- 4.
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
status="match"
|
|
262
|
-
)))
|
|
263
|
-
main_cursor += 1
|
|
264
|
-
gold_cursor += 1
|
|
265
|
-
|
|
266
|
-
elif isinstance(item, Extra):
|
|
267
|
-
if item.extra_type == ExtraType.PAYLOAD:
|
|
268
|
-
# Word in main but not in gold -> extra_main (+)
|
|
269
|
-
orig_main_idx = main_map[main_cursor]
|
|
270
|
-
main_utt_idx = main_info[orig_main_idx][0]
|
|
271
|
-
main_form_idx = main_info[orig_main_idx][1]
|
|
272
|
-
main_form = main_info[orig_main_idx][2]
|
|
273
|
-
current_main_utt = main_utt_idx
|
|
274
|
-
last_main_form_idx = main_form_idx
|
|
298
|
+
# --- 4. Partition conformed gold tokens by utterance ---
|
|
299
|
+
gold_utt_tokens = {i: [] for i in range(len(gold_utterances))}
|
|
300
|
+
gold_utt_maps = {i: [] for i in range(len(gold_utterances))}
|
|
301
|
+
for j in range(len(conformed_gold)):
|
|
302
|
+
orig_idx = gold_map[j]
|
|
303
|
+
utt_idx = gold_info[orig_idx][0]
|
|
304
|
+
gold_utt_tokens[utt_idx].append(conformed_gold[j])
|
|
305
|
+
gold_utt_maps[utt_idx].append(orig_idx)
|
|
306
|
+
|
|
307
|
+
# --- 5. Per-utterance alignment ---
|
|
308
|
+
# For each gold utterance, find a rough last-possible bag-of-words
|
|
309
|
+
# window in the remaining main tokens, then run Levenshtein inside
|
|
310
|
+
# that window to produce the annotations.
|
|
311
|
+
utt_positioned = {i: [] for i in range(len(gold_utterances))}
|
|
312
|
+
search_start = 0
|
|
313
|
+
|
|
314
|
+
for utt_idx in range(len(gold_utterances)):
|
|
315
|
+
g_tokens = gold_utt_tokens[utt_idx]
|
|
316
|
+
g_maps = gold_utt_maps[utt_idx]
|
|
317
|
+
G = len(g_tokens)
|
|
318
|
+
|
|
319
|
+
if G == 0:
|
|
320
|
+
continue
|
|
275
321
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
322
|
+
remaining_main = conformed_main[search_start:]
|
|
323
|
+
win_start, win_end = _find_best_segment(g_tokens, remaining_main, match_fn)
|
|
324
|
+
|
|
325
|
+
abs_start = search_start + win_start
|
|
326
|
+
abs_end = search_start + win_end
|
|
327
|
+
|
|
328
|
+
# Align the chosen window against this gold utterance
|
|
329
|
+
window_main = conformed_main[abs_start:abs_end]
|
|
330
|
+
utt_alignment = align(window_main, g_tokens, False, match_fn)
|
|
331
|
+
|
|
332
|
+
local_main_cursor = 0
|
|
333
|
+
local_gold_cursor = 0
|
|
334
|
+
last_gold_form_idx = -1
|
|
282
335
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
336
|
+
for item in utt_alignment:
|
|
337
|
+
if isinstance(item, Match):
|
|
338
|
+
global_main_idx = abs_start + local_main_cursor
|
|
339
|
+
orig_main_idx = main_map[global_main_idx]
|
|
340
|
+
main_form = main_info[orig_main_idx][2]
|
|
341
|
+
orig_gold_idx = g_maps[local_gold_cursor]
|
|
342
|
+
gold_form_idx = gold_info[orig_gold_idx][1]
|
|
286
343
|
gold_form = gold_info[orig_gold_idx][2]
|
|
344
|
+
last_gold_form_idx = gold_form_idx
|
|
345
|
+
|
|
346
|
+
if main_form.time is not None:
|
|
347
|
+
gold_form.time = main_form.time
|
|
348
|
+
if main_form.morphology is not None:
|
|
349
|
+
gold_form.morphology = main_form.morphology
|
|
350
|
+
if main_form.dependency is not None:
|
|
351
|
+
gold_form.dependency = main_form.dependency
|
|
287
352
|
|
|
288
|
-
|
|
289
|
-
pos = last_main_form_idx + 0.5
|
|
290
|
-
utt_positioned[current_main_utt].append((pos, CompareToken(
|
|
353
|
+
utt_positioned[utt_idx].append((gold_form_idx, CompareToken(
|
|
291
354
|
text=item.key,
|
|
292
|
-
pos=_get_pos(
|
|
293
|
-
status="
|
|
355
|
+
pos=_get_pos(main_form),
|
|
356
|
+
status="match"
|
|
294
357
|
)))
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
358
|
+
local_main_cursor += 1
|
|
359
|
+
local_gold_cursor += 1
|
|
360
|
+
|
|
361
|
+
elif isinstance(item, Extra):
|
|
362
|
+
if item.extra_type == ExtraType.REFERENCE:
|
|
363
|
+
orig_gold_idx = g_maps[local_gold_cursor]
|
|
364
|
+
gold_form_idx = gold_info[orig_gold_idx][1]
|
|
365
|
+
gold_form = gold_info[orig_gold_idx][2]
|
|
366
|
+
last_gold_form_idx = gold_form_idx
|
|
367
|
+
|
|
368
|
+
utt_positioned[utt_idx].append((gold_form_idx, CompareToken(
|
|
369
|
+
text=item.key,
|
|
370
|
+
pos=_get_pos(gold_form),
|
|
371
|
+
status="extra_gold"
|
|
372
|
+
)))
|
|
373
|
+
local_gold_cursor += 1
|
|
374
|
+
|
|
375
|
+
else:
|
|
376
|
+
global_main_idx = abs_start + local_main_cursor
|
|
377
|
+
orig_main_idx = main_map[global_main_idx]
|
|
378
|
+
main_form = main_info[orig_main_idx][2]
|
|
379
|
+
|
|
380
|
+
pos = last_gold_form_idx + 0.5
|
|
381
|
+
utt_positioned[utt_idx].append((pos, CompareToken(
|
|
382
|
+
text=item.key,
|
|
383
|
+
pos=_get_pos(main_form),
|
|
384
|
+
status="extra_main"
|
|
385
|
+
)))
|
|
386
|
+
local_main_cursor += 1
|
|
387
|
+
|
|
388
|
+
search_start = abs_end
|
|
389
|
+
|
|
390
|
+
# --- 6. Merge punctuation from gold at original positions ---
|
|
391
|
+
for utt_idx in range(len(gold_utterances)):
|
|
392
|
+
for form_idx, form in gold_punct[utt_idx]:
|
|
300
393
|
utt_positioned[utt_idx].append((form_idx, CompareToken(
|
|
301
394
|
text=form.text,
|
|
302
395
|
pos="PUNCT",
|
|
303
396
|
status="match"
|
|
304
397
|
)))
|
|
305
|
-
|
|
398
|
+
# Ensure punctuation forms have morphology so %mor includes
|
|
399
|
+
# the final delimiter (matches generator's PUNCT|<char> logic)
|
|
400
|
+
if form.morphology is None:
|
|
401
|
+
form.morphology = [Morphology(
|
|
402
|
+
pos="PUNCT", lemma=form.text.strip(), feats=""
|
|
403
|
+
)]
|
|
306
404
|
utt_positioned[utt_idx].sort(key=lambda x: x[0])
|
|
307
405
|
|
|
308
|
-
# --- 7. Set comparison on each utterance ---
|
|
309
|
-
for utt_idx, utt in enumerate(
|
|
406
|
+
# --- 7. Set comparison on each gold utterance ---
|
|
407
|
+
for utt_idx, utt in enumerate(gold_utterances):
|
|
310
408
|
tokens = [tok for _, tok in utt_positioned[utt_idx]]
|
|
311
409
|
utt.comparison = tokens if tokens else None
|
|
312
410
|
|
|
313
|
-
|
|
411
|
+
timed_forms = [form for form in utt.content if form.time is not None]
|
|
412
|
+
if timed_forms:
|
|
413
|
+
utt.time = (timed_forms[0].time[0], timed_forms[-1].time[1])
|
|
414
|
+
utt.text = None
|
|
415
|
+
|
|
416
|
+
return gold
|
|
314
417
|
|
|
315
418
|
|
|
316
419
|
class CompareAnalysisEngine(BatchalignEngine):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/models/utterance/cantonese_infer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/asr/num2lang/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/cleanup/disfluencies.py
RENAMED
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/cleanup/parse_support.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/cleanup/support/test.test
RENAMED
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/diarization/__init__.py
RENAMED
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/diarization/pyannote.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/morphosyntax/__init__.py
RENAMED
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/morphosyntax/coref.py
RENAMED
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/morphosyntax/en/irr.py
RENAMED
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/morphosyntax/fr/apm.py
RENAMED
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/morphosyntax/fr/apmn.py
RENAMED
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/morphosyntax/fr/case.py
RENAMED
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/morphosyntax/ja/verbforms.py
RENAMED
|
File without changes
|
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/opensmile/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/speaker/nemo_speaker.py
RENAMED
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/translate/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/translate/seamless.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/utterance/__init__.py
RENAMED
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/pipelines/utterance/ud_utterance.py
RENAMED
|
File without changes
|
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/cli/test_dispatch_memory.py
RENAMED
|
File without changes
|
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/formats/chat/test_chat_file.py
RENAMED
|
File without changes
|
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/formats/chat/test_chat_lexer.py
RENAMED
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/formats/chat/test_chat_parser.py
RENAMED
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/formats/chat/test_chat_utils.py
RENAMED
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/formats/textgrid/test_textgrid.py
RENAMED
|
File without changes
|
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/models/test_audio_lazy.py
RENAMED
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/pipelines/analysis/test_eval.py
RENAMED
|
File without changes
|
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/pipelines/asr/test_asr_utils.py
RENAMED
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/pipelines/cache/__init__.py
RENAMED
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/pipelines/cache/test_cache.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/pipelines/fa/test_fa_pipeline.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/pipelines/test_pipeline.py
RENAMED
|
File without changes
|
{batchalign-0.8.2.post1 → batchalign-0.8.2.post3}/batchalign/tests/pipelines/test_pipeline_models.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|