diff --git a/.github/workflows/docker_pull.yml b/.github/workflows/docker_pull.yml index 58b90280..9ac0a4cf 100644 --- a/.github/workflows/docker_pull.yml +++ b/.github/workflows/docker_pull.yml @@ -21,7 +21,9 @@ jobs: - name: Build Docker image run: | - docker build -t sdp-test-image:${{ github.sha }} -f docker/Dockerfile . + docker build -t sdp-test-image:${{ github.sha }} \ + -f docker/Dockerfile \ + --build-arg SOURCE=./ . - name: Run test tests run: | diff --git a/.github/workflows/test_e2e_datasets.yml b/.github/workflows/test_e2e_datasets.yml new file mode 100644 index 00000000..c968fd32 --- /dev/null +++ b/.github/workflows/test_e2e_datasets.yml @@ -0,0 +1,43 @@ +name: E2E Dataset Pipelines Docker Build and Test + +on: + pull_request: + branches: [ "main" ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +permissions: + contents: read + +jobs: + Granary: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" + - name: Install dependencies + run: | + python -m pip install --upgrade pip && \ + find requirements/ -maxdepth 1 -name "*.txt" -exec pip install -r {} && \ + pip install -r requirements/datasets/granary.txt && \ + python -m pip cache purge + + - name: Run Yodas2 E2E test + # in the future this might fail if some runtime tests require nemo + # in that case this test will need to be changed + run: | + python -m pytest tests/test_utils.py -v + + - name: Get test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results + path: | + pytest.xml + coverage.xml \ No newline at end of file diff --git a/.gitignore b/.gitignore index 559fd1bd..eba37666 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ test_data workdir lightning_logs +build # unit test / coverage reports .hypothesis diff --git a/dataset_configs/arabic/masc/config_filter_noisy_train.yaml b/dataset_configs/arabic/masc/config_filter_noisy_train.yaml index 8059177d..767768af 100644 --- a/dataset_configs/arabic/masc/config_filter_noisy_train.yaml +++ b/dataset_configs/arabic/masc/config_filter_noisy_train.yaml @@ -282,10 +282,12 @@ processors: output_manifest_file: ${manifest_dir}/manifest21.json # 22 keeping only low WER and CER samples - - _target_: sdp.processors.ApplyInnerJoin + - _target_: sdp.processors.JoinManifests left_manifest_file: ${manifest_dir}/manifest21.json right_manifest_file: ${manifest_dir}/manifest19.json - column_id: audio_filepath + merge_params: + 'on': audio_filepath + how: inner output_manifest_file: ${manifest_dir}/manifest22.json # 23 changing paths to relative diff --git a/dataset_configs/granary/readme.md b/dataset_configs/granary/readme.md deleted file mode 100644 index 51f4da28..00000000 --- a/dataset_configs/granary/readme.md +++ /dev/null @@ -1,5 +0,0 @@ -# README - -This folder is designated for Granary speech data processing configuration files will be added soon. It is associated with a forthcoming paper, which will detail the work done within this project. - -Note: This folder is a work in progress. diff --git a/dataset_configs/multilingual/granary/README.md b/dataset_configs/multilingual/granary/README.md new file mode 100644 index 00000000..7a9407e9 --- /dev/null +++ b/dataset_configs/multilingual/granary/README.md @@ -0,0 +1,18 @@ +# README + +This folder is designated for Granary speech data processing configuration files will be added soon. It is associated with a forthcoming paper, which will detail the work done within this project. + +Note: This folder is a work in progress. + +# Granary + +## Yodas2 + +### Convert to tarred audio dataset +Suggested values for parameters like num_shards and buckets_num depend on the selected `source_lang` and whether `en_translation` is enabled. These values are provided below to help efficiently prepare a ready-to-train tarred audio dataset. + +| `source_lang` | `bg` | `bg` | `cs` | `cs` | `da` | `da` | `de` | `de` | `el` | `el` | `en` | `es` | `es` | `et` | `et` | `fi` | `fi` | `fr` | `fr` | `hr` | `hr` | `hu` | `hu` | `it` | `it` | `lt` | `lt` | `lv` | `lv` | `nl` | `nl` | `pl` | `pl` | `pt` | `pt` | `ro` | `ro` | `ru` | `ru` | `sk` | `sk` | `sv` | `sv` | `uk` | `uk` | +|------------------|:-----:|:----:|:-----:|:----:|:-----:|:----:|:-----:|:----:|:-----:|:----:|:-----:|:-----:|:----:|:-----:|:----:|:-----:|:----:|:-----:|:----:|:-----:|:----:|:-----:|:----:|:-----:|:----:|:-----:|:----:|:-----:|:----:|:-----:|:----:|:-----:|:----:|:-----:|:----:|:-----:|:----:|:-----:|:----:|:-----:|:----:|:-----:|:----:|:-----:|:----:| +| `en_translation` | `False` | `True` | `False` | `True` | `False` | `True` | `False` | `True` | `False` | `True` | `False` | `False` | `True` | `False` | `True` | `False` | `True` | `False` | `True` | `False` | `True` | `False` | `True` | `False` | `True` | `False` | `True` | `False` | `True` | `False` | `True` | `False` | `True` | `False` | `True` | `False` | `True` | `False` | `True` | `False` | `True` | `False` | `True` | `False` | `True` | +| `num_shards` | 16 | 16 | 32 | 32 | 16 | 16 | 4096 | 1024 | 16 | 16 | 8192 | 8192 | 1024 | 16 | 16 | 64 | 32 | 4096 | 1024 | 16 | 16 | 64 | 32 | 1024 | 1024 | 16 | 16 | 16 | 16 | 1024 | 512 | 256 | 256 | 4096 | 4096 | 16 | 16 | 8192 | 1024 | 16 | 16 | 64 | 32 | 128 | 128 | +| `buckets_num` | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 4 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | diff --git a/dataset_configs/multilingual/granary/yodas2.yaml b/dataset_configs/multilingual/granary/yodas2.yaml new file mode 100644 index 00000000..600e5c3c --- /dev/null +++ b/dataset_configs/multilingual/granary/yodas2.yaml @@ -0,0 +1,236 @@ +documentation: | + YODAS2 Data Processing Pipeline + ============================== + + This pipeline processes the YODAS2 subset of the Granary dataset, which consists of long-form multilingual YouTube speech data + with timestamps and transcriptions. It downloads, normalizes, filters, converts, and packages the data into a tarred audio dataset + format suitable for training speech models with NeMo. + + Overview + -------- + The pipeline automatically downloads all required metadata and audio data, applies text normalization and filtering, converts audio + to the standard format, and generates a final Granary dataset in *tarred audio format*. + + The pipeline is designed to process data for a specific source language, which must be one of the following supported languages: + + :: + + "bg", "cs", "da", "de", "el", "en", "es", "et", "fi", "fr", + "hr", "hu", "it", "lt", "lv", "nl", "pl", "pt", "ro", "ru", "sk", "sv", "uk" + + Configuration Parameters + ------------------------ + - **use_dask**: Whether to use Dask for multiprocessing (recommended: False) + - **params**: + - **source_lang**: Language code (e.g., "bg" for Bulgarian) + - **use_regex**: Regex rules to apply. Usually set to the same value as `source_lang`, or to `"common"` to apply a universal normalization pattern across 25 languages. + - **en_translation**: Whether to include English translations (default: True) + - **convert_to_audio_tarred_dataset**: + - **should_run**: Whether to convert to tarred audio format + - **num_shards**: Number of tar shards + - **buckets_num**: Number of buckets for duration grouping + - **min_audio_duration** / **max_audio_duration**: Duration filters (in seconds) + - **save_disk_space**: Whether to delete intermediate files (default: True) + - **use_snapshot_download**: Whether to use snapshot_download from Hugging Face (default: False) + + Output + ------ + After execution, the pipeline produces: + + - A **tarred audio dataset**, which contains: + - Converted audio files in 16 kHz mono WAV format + - Corresponding manifests with cleaned and normalized transcripts + - Optionally, English translations + + Running the Pipeline + -------------------- + Run this command to launch the pipeline: + + .. code-block:: bash + + python main.py \ + --config-path=dataset_configs/multilingual/granary/ \ + --config-name=yodas2.yaml + + References + ---------- + - YODAS2 on Hugging Face: https://huggingface.co/datasets/espnet/yodas2 + + Summary + ------- + This pipeline prepares filtered, normalized, and language-specific audio data in a format ready for training NeMo-compatible ASR models. + +use_dask: False # Whether to use Dask for multiprocessing. False = use built-in processing (recommended). + +params: + source_lang: ?? # Set the language to process (e.g., "bg") + use_regex: ${.source_lang} # Regex config for text normalization. Usually same as the language, or "common" to apply a universal regex for 25 languages. + en_translation: True # If True, download also English translations (if available). + convert_to_audio_tarred_dataset: + should_run: True # If True, the final tarred dataset will be created. + num_shards: ?? # Number of tar files to split the dataset into. + buckets_num: ?? # Number of duration buckets (used for balancing durations across shards). + min_audio_duration: 0.1 # Exclude files shorter than 0.1 seconds. + max_audio_duration: 40.0 # Exclude files longer than 40 seconds. + save_disk_space: True # If True, intermediate audio files will be deleted. + use_snapshot_download: False # If True, use snapshot_download instead of Hugging Face Hub APIs. + +processors_to_run: "all" # Run all processors in sequence. + +workspace_dir: ?? # Required: output directory to save all intermediate and final files. +sdp_dir: ./NeMo-speech-data-processor # Path to the local clone of the SDP repo. + +processors: + # 0. Get base manifest (JSONL with audio references and text) + - _target_: sdp.processors.GetGranarysYodas2 + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_00.json + lang: ${params.source_lang} + translation: ${params.en_translation} + + # 1. Apply regex-based substitutions to normalize text + - _target_: sdp.processors.SubRegex + text_key: text + regex_params_yaml: ${sdp_dir}/dataset_configs/multilingual/yodas2/partials/subregex_params/${params.use_regex}.yaml + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_01.json + + # 2. Drop empty or whitespace-only entries + - _target_: sdp.processors.DropIfRegexMatch + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_02.json + text_key: text + regex_patterns: + - "^\\s*$" + + # 3. Expand metadata (adds lang_subset, shard_id, etc.) + - _target_: sdp.processors.ListYodas2Data + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_03.json + use_metadata: True + + # 4. Remove unused fields + - _target_: sdp.processors.DropSpecifiedFields + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_04.json + fields_to_drop: + - duration_key + - text_key + + # 5. Add `source_lang` field based on lang_subset prefix + - _target_: sdp.processors.LambdaExpression + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_05.json + new_field: source_lang + expression: entry.lang_subset[:2] + + # 6. Keep only entries where source_lang matches config + - _target_: sdp.processors.PreserveByValue + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_06.json + input_value_key: source_lang + target_value: ${params.source_lang} + + # 7. Download tarballs with snapshot_download (if enabled) + - _target_: sdp.processors.SnapshotDownloadYodas2Data + should_run: ${params.use_snapshot_download} + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_07.json + local_dir: ${workspace_dir}/${params.source_lang}/ + max_workers: 8 + + # 8. Download tarballs via HF Hub API (default path) + - _target_: sdp.processors.HfHubDownloadYodas2Data + input_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_06.json + should_run: ${not:${params.use_snapshot_download}} + filename_field: audio_key + output_filepath_field: local_audio + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_07.json + hf_hub_download_args: + local_dir: ${workspace_dir}/${params.source_lang}/ + max_workers: 8 + + # 9. Extract .tar files into audio WAVs + - _target_: sdp.processors.ExtractTar + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_08.json + field_to_tar_filepath: 'local_audio' + extraction_dir: ${workspace_dir}/${params.source_lang} + remove_source_tar: ${params.save_disk_space} + filepath_prefix_field: 'lang_subset' + output_filepath_field: 'extracted_audios' + get_extracted_filepaths: True + + # 10. Flatten lists of extracted audio paths + - _target_: sdp.processors.ListToEntries + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_09.json + field_with_list: 'extracted_audios' + output_field: 'source_audio_filepath' + + # 11. Add yodas_id (unique audio ID) from filename + - _target_: sdp.processors.LambdaExpression + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_10.json + new_field: 'yodas_id' + expression: "entry.source_audio_filepath[-15:-4]" + + # 12. Define the final audio output path for conversion + - _target_: sdp.processors.LambdaExpression + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_11.json + new_field: 'audio_filepath' + expression: "'${workspace_dir}/${params.source_lang}/converted/' + entry.lang_subset + '/' + entry.shard_id + '/' + entry.yodas_id" + + # 13. Convert audio to 16kHz mono WAV + - _target_: sdp.processors.FfmpegConvert + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_12.json + input_file_key: 'source_audio_filepath' + output_file_key: 'audio_filepath' + id_key: 'audio_filepath' + converted_audio_dir: '/' + target_samplerate: 16000 + target_nchannels: 1 + + # 14. Optionally remove the original raw audio files + - _target_: sdp.processors.RemoveFiles + filepath_field: 'source_audio_filepath' + should_run: ${params.save_disk_space} + + # 15. Keep only fields needed for final merge + - _target_: sdp.processors.KeepOnlySpecifiedFields + input_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_12.json + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_13.json + fields_to_keep: + - yodas_id + - audio_filepath + + # 16. Merge audio paths with filtered text + - _target_: sdp.processors.JoinManifests + left_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_02.json + right_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_13.json + merge_params: + 'on': yodas_id + how: inner + copy: False + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_14.json + + # 17. Add fields required for Canary model + - _target_: sdp.processors.AddConstantFields + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_15.json + fields: + decodercontext: "" + "emotion": "<|emo:undefined|>" + "pnc": "pnc" + "itn": "itn" + "timestamp": "notimestamp" + "diarize": "nodiarize" + + # 18. Create the final tarred audio dataset + - _target_: sdp.processors.ConvertToTarredAudioDataset + should_run: ${params.convert_to_audio_tarred_dataset.should_run} + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_16.json + min_duration: ${params.convert_to_audio_tarred_dataset.min_audio_duration} + max_duration: ${params.convert_to_audio_tarred_dataset.max_audio_duration} + target_dir: ${workspace_dir}/${params.source_lang}/tarred_dataset + num_shards: ${params.convert_to_audio_tarred_dataset.num_shards} + buckets_num: ${params.convert_to_audio_tarred_dataset.buckets_num} + workers: -1 + shuffle: True + shuffle_seed: 1 + sort_in_shards: True + slice_with_offset: True + + # 19. Optionally delete final converted audio files + - _target_: sdp.processors.RemoveFiles + input_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_17.json + filepath_field: 'audio_filepath' + should_run: ${params.save_disk_space} diff --git a/dataset_configs/multilingual/yodas2/config.yaml b/dataset_configs/multilingual/yodas2/config.yaml new file mode 100644 index 00000000..b116c501 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/config.yaml @@ -0,0 +1,457 @@ +documentation: | + YODAS2 + ############ + Documentation is in progress. + +use_dask: False + +params: + source_lang: en + source_lang_full: English + min_audio_lid_probability: 0.7 + min_audio_duration: 0.1 + max_audio_duration: 40.0 + use_regex: common + translation: + target_lang: it + target_lang_full: Italian + max_len_diff_ratio: 4 + min_hist_token_ratio: 0.8 + min_text_lid_probability: 0.3 + min_qe_score: 0.75 + convert_to_audio_tarred_dataset: + should_run: True + num_shards: 16 + buckets_num: 1 + save_disk_space: False + use_snapshot_download: False + +processors_to_run: "7:" +workspace_dir: /data3/sdp_test/test_hf/_prep/ #/data3/sdp_test/final_test +sdp_dir: /ameister/YODAS_PR_FINAL/NeMo-speech-data-processor + +processors: + - _target_: sdp.processors.ListYodas2Data + output_manifest_file: ${workspace_dir}/manifest_00.json + use_metadata: True + + - _target_: sdp.processors.LambdaExpression + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_01.json + new_field: source_lang + expression: entry.lang_subset[:2] + + - _target_: sdp.processors.PreserveByValue + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_02.json + input_value_key: source_lang + target_value: ${params.source_lang} + + - _target_: sdp.processors.SnapshotDownloadYodas2Data + should_run: ${params.use_snapshot_download} + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_03.json + local_dir: ${workspace_dir}/${params.source_lang}/ + max_workers: 8 + + - _target_: sdp.processors.HfHubDownloadYodas2Data + should_run: ${not:${params.use_snapshot_download}} + filename_field: audio_key + output_filepath_field: local_audio + output_manifest_file: ${workspace_dir}/${params.source_lang}/.yodas2_hf_hub/manifest_03_01.json + local_dir: ${workspace_dir}/${params.source_lang}/ + max_workers: 8 + + - _target_: sdp.processors.HfHubDownloadYodas2Data + should_run: ${not:${params.use_snapshot_download}} + filename_field: duration_key + output_filepath_field: local_duration + output_manifest_file: ${workspace_dir}/${params.source_lang}/.yodas2_hf_hub/manifest_03_02.json + local_dir: ${workspace_dir}/${params.source_lang}/ + max_workers: 8 + + - _target_: sdp.processors.HfHubDownloadYodas2Data + should_run: ${not:${params.use_snapshot_download}} + filename_field: text_key + output_filepath_field: local_text + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_03.json + local_dir: ${workspace_dir}/${params.source_lang}/ + max_workers: 8 + + - _target_: sdp.processors.ExtractTar + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_04.json + field_to_tar_filepath: 'local_audio' + extraction_dir: ${workspace_dir}/${params.source_lang} + remove_source_tar: ${params.save_disk_space} + filepath_prefix_field: 'lang_subset' + output_filepath_field: 'extracted_audios' + get_extracted_filepaths: True + + - _target_: sdp.processors.CreateInitialManifestYodas2 + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_05.json + field_with_list: 'extracted_audios' + output_field: 'source_audio_filepath' + fields_to_save: + - lang_subset + - shard_id + - source_lang + + - _target_: sdp.processors.LambdaExpression + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_06.json + new_field: 'audio_filepath' + expression: "'${workspace_dir}/${params.source_lang}/converted/' + entry.lang_subset + '/' + entry.shard_id + '/' + entry.yodas_id" + + - _target_: sdp.processors.FfmpegConvert + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_07.json + input_file_key: 'source_audio_filepath' + output_file_key: 'audio_filepath' + id_key: 'audio_filepath' + converted_audio_dir: '/' + target_samplerate: 16000 + target_nchannels: 1 + + - _target_: sdp.processors.RemoveFiles + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_08.json + filepath_field: 'source_audio_filepath' + should_run: ${params.save_disk_space} + + # Lang ID + - _target_: sdp.processors.FasterWhisperInference + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_09.json + model_size_or_path: 'base' + num_devices: -1 + output_dir: ${workspace_dir}/${params.source_lang}/manifest_09 + language_detection_only: True + inference: + language_detection_segments: 7 + chunk_length: 30 + save_timestamps_separately: False + skip_corrupted_audios: True + + - _target_: sdp.processors.LambdaExpression + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_10.json + new_field: 'lid_verified' + expression: (entry.language == "${params.source_lang}") & (entry.language_probability >= ${params.min_audio_lid_probability}) + filter: True + + - _target_: sdp.processors.DropSpecifiedFields + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_11.json + fields_to_drop: + - language + - language_probability + - lid_verified + + # Inference on long audio + - _target_: sdp.processors.FasterWhisperInference + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_12.json + model_size_or_path: 'base' + output_dir: ${workspace_dir}/${params.source_lang}/manifest_12 + num_devices: -1 + inference: + language: ${params.source_lang} + save_timestamps_separately: False + skip_corrupted_audios: True + + - _target_: sdp.processors.ListToEntries + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_13.json + field_with_list: 'segments' + + - _target_: sdp.processors.LambdaExpression + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_14.json + new_field: 'duration' + expression: entry.end - entry.start + + - _target_: sdp.processors.DropHighLowDuration + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_14a.json + high_duration_threshold: ${params.max_audio_duration} + low_duration_threshold: ${params.min_audio_duration} + + - _target_: sdp.processors.RenameFields + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_15.json + rename_fields: + start: offset + id: segment_id + language: source_lang + + - _target_: sdp.processors.KeepOnlySpecifiedFields + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_16.json + fields_to_keep: + - lang_subset + - shard_id + - yodas_id + - source_lang + - audio_filepath + - segment_id + - offset + - duration + + - _target_: sdp.processors.FasterWhisperInference + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_17.json + model_size_or_path: 'base' + num_devices: -1 + output_dir: ${workspace_dir}/${params.source_lang}/manifest_17 + inference: + language: ${params.source_lang} + save_timestamps_separately: False + skip_corrupted_audios: True + slice_by_offset: True + + - _target_: sdp.processors.KeepOnlySpecifiedFields + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_18.json + fields_to_keep: + - lang_subset + - shard_id + - yodas_id + - source_lang + - audio_filepath + - segment_id + - offset + - duration + - pred_text + + - _target_: sdp.processors.RenameFields + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_19.json + rename_fields: + pred_text: text + + - _target_: sdp.processors.DropIfRegexMatch + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_20.json + text_key: text + regex_patterns: + - "^\\s*$" + + - _target_: sdp.processors.DetectWhisperHallucinationFeatures + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_21.json + common_hall_file: ${sdp_dir}/dataset_configs/multilingual/granary/partials/common_phrases/${params.source_lang}.txt + text_field: text + + - _target_: sdp.processors.LambdaExpression + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_22.json + new_field: is_hallucinated + expression: (not entry.hall_repeated_ngrams) & (not entry.hall_long_word) & (not entry.hall_frequent_single_word) + filter: True + + - _target_: sdp.processors.KeepOnlySpecifiedFields + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_23.json + fields_to_keep: + - lang_subset + - shard_id + - yodas_id + - source_lang + - audio_filepath + - segment_id + - offset + - duration + - text + + - _target_: sdp.processors.vLLMInference + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_24.json + generation_field: src_text + prompt_file: ${sdp_dir}/dataset_configs/multilingual/granary/partials/pr_recovery_prompts/${params.source_lang}.yaml + model: + model: "Qwen/Qwen2.5-0.5B-Instruct" #"Qwen/Qwen2.5-7B-Instruct-1M" + tensor_parallel_size: 2 + max_model_len: 2048 + enable_chunked_prefill: True + max_num_batched_tokens: 1024 + enforce_eager: True + dtype: float16 + gpu_memory_utilization: 0.95 + max_num_seqs: 16 + inference: + temperature: 0.7 + top_p: 0.8 + repetition_penalty: 1.05 + max_tokens: 2048 + apply_chat_template: + tokenize: False + add_generation_prompt: True + + - _target_: sdp.processors.CleanQwenGeneration + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_25.json + text_field: text + generation_field: src_text + + - _target_: sdp.processors.SubRegex + text_key: src_text + regex_params_yaml: ${sdp_dir}/dataset_configs/multilingual/granary/partials/subregex_params/${params.use_regex}.yaml + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_26.json + + - _target_: sdp.processors.DropSpecifiedFields + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_27.json + fields_to_drop: + - text + + # AST + - _target_: sdp.processors.AddConstantFields + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_28.json + fields: + target_lang: ${params.translation.target_lang} + + - _target_: sdp.processors.vLLMInference + generation_field: tgt_text + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_29.json + prompt: + system: "" + user: | + Translate the following ${params.source_lang_full} source text to ${params.translation.target_lang_full}: + ${params.source_lang_full}: {src_text} + ${params.translation.target_lang_full}: + model: + model: "utter-project/EuroLLM-1.7B-Instruct" #"utter-project/EuroLLM-9B-Instruct" + dtype: float16 + tensor_parallel_size: 2 + inference: + best_of: 1 + temperature: 0.0 + top_p: 1.0 + max_tokens: 1280 + apply_chat_template: + max_length: 512 + tokenize: False + add_generation_prompt: True + + ## num_words and len_diff_ratio filtering + - _target_: sdp.processors.CountNumWords + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_30.json + text_key: src_text + num_words_key: num_words_src + + - _target_: sdp.processors.CountNumWords + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_31.json + text_key: tgt_text + num_words_key: num_words_tgt + + - _target_: sdp.processors.LambdaExpression + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_32.json + new_field: num_words_filter + expression: (entry.num_words_src > 1) & (entry.num_words_tgt > 1) + filter: True + + - _target_: sdp.processors.LambdaExpression + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_33.json + new_field: len_diff_ratio + expression: max(entry.num_words_src / entry.num_words_tgt, entry.num_words_tgt / entry.num_words_src) + + - _target_: sdp.processors.PreserveByValue + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_34.json + input_value_key: len_diff_ratio + operator: lt + target_value: ${params.translation.max_len_diff_ratio} + + - _target_: sdp.processors.DropSpecifiedFields + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_35.json + fields_to_drop: + - num_words_src + - num_words_tgt + - num_words_filter + - len_diff_ratio + + ## filtering based on character histograms + - _target_: sdp.processors.FilterWithCharacterHistograms + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_36.json + text_field: src_text + lang: ${params.source_lang} + output_score_field: src_hist_token_ratio + cache_dir: /data3/sdp_test/cache/histograms + + - _target_: sdp.processors.FilterWithCharacterHistograms + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_37.json + text_field: tgt_text + lang: ${params.translation.target_lang} + output_score_field: tgt_hist_token_ratio + cache_dir: /data3/sdp_test/cache/histograms + + - _target_: sdp.processors.LambdaExpression + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_38.json + new_field: len_diff_ratio_filter + expression: (entry.src_hist_token_ratio > ${params.translation.min_hist_token_ratio}) & (entry.tgt_hist_token_ratio > ${params.translation.min_hist_token_ratio}) + filter: True + + - _target_: sdp.processors.DropSpecifiedFields + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_39.json + fields_to_drop: + - src_hist_token_ratio + - tgt_hist_token_ratio + - len_diff_ratio_filter + + ## filtering based on Fasttext LID + - _target_: sdp.processors.FastTextLangIdClassifier + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_40.json + text_field: src_text + output_field: src_lid + model_name_or_path: lid.176.bin + cache_dir: /data3/sdp_test/cache + + - _target_: sdp.processors.FastTextLangIdClassifier + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_41.json + text_field: tgt_text + output_field: tgt_lid + model_name_or_path: lid.176.bin + cache_dir: /data3/sdp_test/cache + + - _target_: sdp.processors.LambdaExpression + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_42.json + new_field: lid_filter + expression: (entry.src_lid == '${params.source_lang}') & (entry.src_lid_prob > ${params.translation.min_text_lid_probability}) & (entry.tgt_lid == '${params.translation.target_lang}') & (entry.tgt_lid_prob > ${params.translation.min_text_lid_probability}) + filter: True + + - _target_: sdp.processors.DropSpecifiedFields + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_43.json + fields_to_drop: + - src_lid + - src_lid_prob + - tgt_lid + - tgt_lid_prob + - lid_filter + + ## filtering based on Cometoid QE + - _target_: sdp.processors.CometoidWMTQualityEstimation + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_44.json + source_text_field: src_text + target_text_field: tgt_text + model_name_or_path: cometoid-wmt23 + device_type: gpu + num_devices: 4 + chunksize: 10 + + - _target_: sdp.processors.PreserveByValue + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_45.json + input_value_key: cometoid_score + operator: gt + target_value: ${params.translation.min_qe_score} + + - _target_: sdp.processors.DropSpecifiedFields + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_46.json + fields_to_drop: + - cometoid_score + + - _target_: sdp.processors.AddConstantFields + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_47.json + fields: + decodercontext: "" + "emotion": "<|emo:undefined|>" + "pnc": "pnc" + "itn": "itn" + "timestamp": "notimestamp" + "diarize": "nodiarize" + + - _target_: sdp.processors.RenameFields + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_48.json + rename_fields: + src_text: text + tgt_text: answer + + - _target_: sdp.processors.ConvertToTarredAudioDataset + should_run: ${params.convert_to_audio_tarred_dataset.should_run} + output_manifest_file: ${workspace_dir}/${params.source_lang}/manifest_49.json + min_duration: ${params.min_audio_duration} + max_duration: ${params.max_audio_duration} + target_dir: ${workspace_dir}/${params.source_lang}/tarred_dataset + num_shards: ${params.convert_to_audio_tarred_dataset.num_shards} + buckets_num: ${params.convert_to_audio_tarred_dataset.buckets_num} + workers: -1 + shuffle: True + shuffle_seed: 1 + sort_in_shards: True + slice_with_offset: True + + #export HF_HOME=/data3/sdp_test/hf/hub/ + #export HYDRA_FULL_ERROR=1 && python /ameister/YODAS_PR_FINAL/NeMo-speech-data-processor/main.py --config-path=/ameister/YODAS_PR_FINAL/NeMo-speech-data-processor/dataset_configs/multilingual/granary/ --config-name=yodas2.yaml \ No newline at end of file diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/bg.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/bg.txt new file mode 100644 index 00000000..4c16dee2 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/bg.txt @@ -0,0 +1,184 @@ +Абонирайте се 2302208 +Егорова 70956 +Семкин Корректор А 68602 +Редактор субтитров А 68129 +Благодаря 15129 +От 2885 +Абонирайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господ 2088 +се 2086 +Корректор А 1050 +Благодаря ви 928 +Българхи 837 +Върху 531 +За 363 +Въпрос 332 +Абонирайте се, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините, господините 325 +Много 300 +Ни 297 +АПЛОДИСМЕНТА 275 +Абон 267 +Против 257 +за 254 +Абонирайте 252 +На 232 +Места 225 +Момент 222 +Борис 220 +Абонирайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се 217 +Мене 213 +Върхава 208 +субтитров А 193 +Въпроса 192 +Благодаря, господин 181 +Минута 176 +Дякую за перегляд 173 +НО 167 +Ви 163 +Ред 159 +Абонираме 159 +господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господ 157 +Свет 152 +Абонирам 151 +Ис 151 +Мир 150 +Мата 149 +Мен 149 +Вина 148 +Върхаме 145 +на 142 +Тили 139 +Мик 138 +Мин 136 +Абонирайте се върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху върху вър 132 +Три 129 +Мята 128 +да 121 +Възможност 120 +Благодаря Ви 120 +Сега 116 +Алиси 115 +Продолжение следует 114 +Продължа ли се 113 +Мастер 112 +Манье 111 +Идеи 111 +Менете 111 +Миси 111 +Мината 111 +Мега 111 +Менок 111 +Малки 110 +Мисли 110 +Медия 110 +Ответа 110 +Майс 109 +Мага 109 +Алик 109 +Вечен 108 +Медел 108 +Меню 108 +Свети 108 +Въздържа ли се 107 +Минут 107 +Меним 105 +Продължението 104 +против 104 +от 103 +Меси 101 +Минути 97 +Но 95 +Субтитры создавал DimaTorzok 94 +Адси 89 +Болич 89 +Отправена 89 +Мен сед 89 +Моги 89 +Риск 88 +Мелници 88 +МОТС 88 +Медомата 88 +Мисия 88 +Малетич 88 +Методи 88 +Веченки 88 +Брифинг 88 +Менути 88 +Майсет 88 +Отговори 88 +Винаги 88 +се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господ 86 +Вдохме 86 +Продължение 86 +господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господ 85 +господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господ 85 +Матсо 85 +Трът 82 +Отвърля се 81 +Телите 81 +процента 80 +Боцена 79 +Месец 79 +Али 77 +О, ние 76 +Двайсет 76 +Една минута 76 +Миште 76 +Венесър 74 +Върхи 73 +Стивилизация 73 +Овреждания 73 +Миколеги 73 +Бълдин 73 +Върнато 73 +Афиоти 73 +Моцелив 73 +се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господ 72 +Благчену 72 +Аз 71 +Приема се 71 +Еди 71 +Абонирайте се, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, господин, госп 69 +се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господ 68 +Отхвърля се 68 +Мозъг 68 +Към четир 66 +Меѓи 64 +Благодаря, господин председател 64 +Афни 63 +Да 63 +Мотив 63 +господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господ 62 +Върши момент 62 +Въпросите 62 +Веден пазар 62 +Менализиране 62 +Вършава 62 +Въпроси 62 +се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господ 61 +Българ 61 +Матеренезик 61 +Върляси 61 +Майко 61 +господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господ 60 +Продължа 60 +По 60 +Три матриси 60 +Майкъл 60 +Бън 60 +Реоформи 58 +Тивата 57 +Бъдете 57 +се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господ 56 +Абонирани 56 +Продългаме 55 +Българси 55 +Модиги 55 +Тъчленки 54 +Пряма-си 54 +се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господинайте се, господ 53 +Волоберем 53 +Мържи 53 +Грозин Мако 53 +Българност 53 +Във холандия 52 +Въздържали се 51 diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/cs.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/cs.txt new file mode 100644 index 00000000..f2b2deba --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/cs.txt @@ -0,0 +1,126 @@ +Titulky vytvořil JohnyX 136094 +Konec 134856 +Děkuji 7495 +Děkujeme 5523 +Titulky vytvořil Jirka Kováč 1660 +JohnyX 778 +Děkuji za pozornost 693 +Hvala 656 +Pro 638 +Kováček 597 +Hrv 425 +vytvořil JohnyX 407 +Tak 388 +Můžeme 277 +Já 248 +Čili 224 +On 222 +to 209 +Ano 207 +Zdravíme 203 +Titulky vytvořil Jirka Kováček 202 +Děkuji za pozornosť 194 +že 192 +Můžete 190 +hradeckralove 170 +pro 160 +Aby 156 +Tv 149 +Kdo 149 +Kino 148 +Rok 148 +Kov 148 +Kole 148 +Skol 148 +A USA 147 +Elections 147 +Elmar 147 +Sv 147 +OSN 147 +Kost 147 +Klet 146 +Ně 146 +Koto 144 +Proti 142 +Kováčku 141 +Kult 141 +109 141 +LL 139 +Kone 138 +proti 136 +A tak 132 +Kováčeku 124 +Zdraví se 122 +Kdo se zdržel 117 +Kolega 111 +Kudov 111 +Klosk 111 +Olibe 111 +Ménota 111 +Růst 110 +Rá 25 110 +První 108 +Analyse 105 +Velkou 104 +Ménote 103 +Čí 103 +Kováč 100 +Ale 98 +Třeba 98 +Jury 8 90 +práva 89 +Ahojte 89 +Osobne 89 +Hrufad 89 +Kolejku 89 +Klasná 89 +Kvěl 89 +Vyrové 88 +Klasovat 87 +com www 81 +A půl 81 +přijato 76 +Vypadáme 74 +Vypadá se 74 +Děkáte 74 +Apočujeme 74 +Dělá se 73 +Oči jde 73 +Přešel 73 +Hvala što pratite kanal 73 +Vyrošet 72 +org www 71 +Necháme se 68 +Konec se 66 +hlasování 64 +Konec 13 64 +Děkujeme pro 63 +procent 63 +Anozovojte 63 +Děkuji vám 62 +Hvala půl 62 +Dnesá dva pro 62 +Kudobel 61 +Ďakujem 60 +Pouštěji 60 +Kolegyně 59 +Amen 58 +protože 58 +Představu 58 +Kováčen 58 +Děvěr 57 +Je 56 +Zdravíte se 56 +Ony 56 +se 55 +Hvala barandikov 55 +Zdravíte 54 +Pánšogor 54 +Číslo jedna 54 +Předstvíte 53 +Vářejnou 53 +Je to představá 51 +Průzat 51 +Vátej klo 51 +Mláme my 51 +Hvala za pozornosť 51 diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/da.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/da.txt new file mode 100644 index 00000000..114d7d6a --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/da.txt @@ -0,0 +1,322 @@ +Danske tekster af Jesper Buhl Scandinavian Text Service 2018 152271 +Danske tekster af Nicolai Winther 128882 +Tak fordi du lyttede med 21659 +Tak fordi du så med 17218 +Tak 16072 +Hvorfor 10744 +Hvad er det 10281 +Danske tekster af Jesper Buhl 3586 +Hvorfor er det 3529 +Vi 3157 +Hr 1928 +Tak for at du så med 1683 +Hvad 1648 +Ja 1415 +Danske tekster af Jesper Buhlsen 1239 +For 1160 +Hvor 1056 +vi 882 +Hvr 782 +Hv 748 +Tak for nu 728 +Tak for mig 715 +Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 671 +En 665 +tekster af Jesper Buhl Scandinavian Text Service 2018 645 +Hvor er det 557 +Winther 503 +Danskevældig 500 +Hvad er det her 485 +Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 465 +Nicolai Winther 452 +Nej 450 +Du 445 +Skål 441 +Hold 437 +Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 434 +Råd 434 +af Nicolai Winther 431 +Hej 428 +Ole 428 +tekster af Nicolai Winther 418 +Hvala 380 +Tak fordi du lyttede 363 +Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 357 +Selv 352 +Tak fordi du lager 345 +Lidt 336 +Så 328 +til 327 +Tak for det 321 +Danske tekst 313 +Hva 312 +Det er det 296 +Kommer 296 +Skal 295 +Godt 286 +Imod 281 +Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 280 +at 280 +Takk for at gøre med 275 +Takk for at du så med 271 +Gud 258 +Om 256 +Takk for 252 +det 238 +Mål 238 +Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 237 +Danske tekster 236 +Jeg 235 +Jeg mener 234 +Værsgo 226 +Fyra 226 +Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 224 +16 223 +Al 222 +Og 221 +2021 217 +og 216 +kom 214 +80 212 +Text 207 +15 200 +28 199 +for 194 +12 194 +Vel 191 +Hvad er 191 +Tak fordi du så 186 +Komisær 183 +med 182 +af Jesper Buhl Scandinavian Text Service 2018 181 +17 178 +20 176 +Men 175 +Amen 173 +Danske tekster af Jesper 164 +Åh 157 +Hvad med det 156 +Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 152 +Lige 151 +Hæ 150 +LK 148 +I mod 148 +mig 148 +Hra 148 +Trat 148 +Pro7 148 +Spil 147 +Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 146 +Kors 146 +Tak for at gøre det 144 +tj 144 +Fy 141 +Holdning 139 +Applåder 136 +Ute 135 +Heard 134 +Hvem er for 125 +Takk 123 +Hvad er det med 121 +Evv 117 +Hvad siger det 115 +Hejdå 114 +Låd 112 +Røst 111 +Brugina 111 +Ræd 111 +Lysen 111 +Låder 111 +Lån 111 +Endelig 111 +Brunnen 111 +URN 111 +Kulir 111 +Mås 111 +her 110 +Hildy 110 +Læf 110 +00 og 3 110 +Horsley 110 +Søs 110 +Tak fordi du hører 109 +Skripper 109 +Hågen 109 +Hildia 109 +Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 108 +Også 107 +Så er det 107 +Hvem er i mod 107 +Læb 107 +Tak for at spørgsmål 107 +Lytter 106 +Tak fordi du med 106 +Tak fordi du lytt 105 +Hvem stemmer for 103 +Takk for at se 102 +Kål 102 +Først 102 +Likowski 99 +Takk for at være med 98 +Et 97 +Tak for 97 +Tak for at være med 97 +Kroner 97 +Danske nu 96 +Kompromis 4 96 +Hvad er sko 95 +Det er ikke 95 +Trænet 95 +Hvorfor er det ikke 92 +Tak fordi du har været med 92 +vedtaget 91 +Hvad er det nu 91 +Mange tak 90 +Kølge 89 +Tak skal du have med 89 +Røsning 89 +Skogårs 89 +Procænd 89 +Kansielers 89 +Vi er imod 89 +Hakeepo 89 +Horslej 89 +Pæs u 89 +Lige produkter 88 +Hvornisk 88 +Røde 88 +Længer 88 +Rapporten 88 +Løsning 88 +Hjelper 88 +Jesper Buhl Scandinavian Text Service 2018 87 +Tak for at du 87 +Haldninger 87 +Femme 13 86 +Hæmmer 86 +Broch 86 +Tak fordi 85 +Forst 85 +Hvad er det så 85 +Svolde 85 +Kjerov 85 +Danske tekster af Jesper Buhlmann 84 +Skal denne 83 +Tine smager 82 +Tak fordi du 81 +Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 80 +Røde 6 80 +11 79 +Kompromis 8 79 +Tak skal du se 79 +Al FimS 78 +Text Service 2018 77 +om 77 +Tak fordi du gør det 77 +Lange 77 +Hvad er den her 75 +En eksempel 75 +Rufløs 74 +Hvorfor med den 74 +Hordel 74 +Hildes politik 74 +Røsninger 74 +Røstegang 74 +er 73 +Hvad gælder 73 +Hæssig 73 +Eksumheder 73 +Buhl Scandinavian Text Service 2018 72 +Tak for dig 72 +Kompromis 2 72 +Ratsificeringen 72 +Scandinavian Text Service 2018 71 +Hvorfor nu 71 +Tak, Hestemes 71 +Femme tuner 71 +Danske tek 71 +Tak fordi du lade det 71 +Læden 71 +Ristemes 71 +Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 70 +Håk han 70 +Hølgen 69 +Hvorfor med 68 +Tak for at gøre 68 +Tak for at gøre med 68 +Hvorfor men 67 +Raffeløren 67 +tak 66 +Multicelle 66 +Tak for me 65 +2018 64 +fordi du lyttede med 64 +så med 64 +Hva er det 64 +Forløp 64 +København 63 +Redskorskj 63 +Hvad tager valg 63 +Læn mig 63 +Skal det ikke 62 +Salabores 62 +Fællet bort 62 +Vænkorska 62 +nu 61 +Vedtaget 61 +Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 Danske tekster af Jesper Buhl Scandinavian Text Service 2018 61 +Tak for at se 61 +Det er tæt 61 +Kjækulia 61 +Rækkelig 61 +Ja, tak 60 +på 60 +13 er også med 60 +Hvis det siger 60 +Hvad slags 60 +Tak fordi jeg rade 59 +Det er ikke det 59 +Tak fordi I do 59 +Næt så 59 +Følgel 59 +Sideraritet 58 +Tak for at sige 57 +Det er med 57 +Fragerudig 57 +Danske med 56 +Danske tekster af Nicolai Winning 55 +Jeg har været løp 55 +Hvorfor tænge 55 +Hvorforstøvning 55 +Fereyra 55 +Det er frukket af mig 55 +Hvis præmulier 54 +Korspinelli 54 +Hvorfor crevier 54 +Erfus Soler 54 +Rødlækken 54 +Hva for dem 54 +Løftkvaliteten 54 +Køyhle 54 +Rekstemt længere 54 +Tak fordi du tæt 54 +Tak, synes du 54 +du så med 53 +Hvad gør du 53 +Hvad er så 53 +Jeg vil gøre 53 +Retspraksis 53 +Ygtighed 53 +lyttede med 52 +Tak skal du 52 +Hvad er det på 52 +Hvorfor det 52 +Tak for at gøre processen 52 +Repo 51 +Tak fordi du prøve 51 +Takk for nu 51 +Tak fordi du så dyr 51 +Holden funder 51 +Hvad er den 51 +Tak fordi du forstår 51 +Det er I 51 diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/de.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/de.txt new file mode 100644 index 00000000..611e6b34 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/de.txt @@ -0,0 +1,8 @@ +Ja 734 +Vielen Dank 518 +Entschuldigung 174 +Dank 150 +Wer ist dafür 81 +Enthaltungen 65 +169 in Fiverr 58 +Dagegen 57 diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/el.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/el.txt new file mode 100644 index 00000000..d5ef53da --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/el.txt @@ -0,0 +1,34 @@ +Υπότιτλοι AUTHORWAVE 152340 +Ευχαριστώ 21201 +Σας ευχαριστώ 9020 +Ωραία 6126 +Ευχαριστούμε 1484 +AUTHORWAVE 1467 +Ευχαριστώ πολύ 611 +Κατά 453 +Υποτιτλοι AUTHORWAVE 361 +Σας ευχαριστούμε 262 +Εγκρίνεται 259 +Αποχές 239 +11 223 +Αποχές εγκρίνεται 160 +Απορρίπτεται 128 +Πέρας 119 +Ωστόσο 112 +Σας ευχαριστώ πολύ 104 +πολύ 93 +Αποχές απορρίπτεται 92 +Πολύ 91 +Εκατόν 89 +Κατά αποχές εγκρίνεται 82 +Άρχεται η ψηφοφορία 80 +Ότι 75 +Παρακαλώ 74 +Πρόεδρε 68 +ευχαριστώ 63 +Εγγρίνεται 62 +ίδιο 62 +και 61 +Ωραίτε 55 +Υπέρ 53 +Οπότε 51 diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/en.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/en.txt new file mode 100644 index 00000000..6e0594c4 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/en.txt @@ -0,0 +1,9 @@ +Thank you 1297 +you 254 +Yeah 217 +Check 117 +Sayemashka 81 +methods 75 +Fifty-four 62 +Amen -1 +Thank you very much -1 diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/es.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/es.txt new file mode 100644 index 00000000..8ab0d60b --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/es.txt @@ -0,0 +1,153 @@ +¡Gracias por ver el video 188372 +Gracias 166346 +Gracias por ver el video 75415 +Gracias, señor presidente 23074 +CC por Antarctica Films Argentina 17436 +Gracias, señora presidenta 8787 +Bien 7478 +¡Gracias 4042 +¿Qué 3549 +¿Qué es lo que se hace 2450 +Chao 2450 +¿Qué pasa 2069 +Salud 1779 +Adiós 1317 +Sí 1224 +video 941 +¡Suscríbete 921 +¿Qué es lo que está pasando 804 +¿Está bien 777 +¿Vale 632 +Más 574 +Muchas gracias 548 +No 499 +Aplausos 497 +Señor 444 +Hola 428 +Ya 426 +Amén 375 +¡Grac 360 +¡Vamos 334 +¡Gracias por ver 325 +Dios mío 281 +¡Suscríbete al canal 274 +¡Gracias por ver el video ¡Gracias por ver el video 270 +aprobada 262 +¿Verdad 250 +Yo 241 +Siguiente 238 +¿Qué es eso 230 +Sal 229 +del 228 +Un 227 +que 223 +Te 222 +Inter 217 +¡Gracias por ver este video 214 +¿En contra 210 +presidente 209 +señor presidente 197 +por ver el video 187 +Muy bien 173 +¿Y 171 +¡Suscríbete y activa la campanita 168 +el video 165 +A ver 163 +¿Qué es lo que se ha hecho 159 +Presidenta 155 +Contra 154 +Lo hago 149 +Teo 149 +Debate 149 +¡Felicidad 148 +Lista 148 +Elma 148 +Plen 148 +No, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, 147 +Corto 147 +¿Cuándo 147 +Empel 146 +Sra 145 +ESF 142 +Aprobada 139 +LL 133 +¿Por qué 130 +¿Alguien 130 +Madre 127 +¿No 126 +POS 126 +En contra 124 +¿Quién es 122 +Gracias, señoras y señores 122 +¿Puedo 121 +Bienvenido 121 +¿Qué es lo que se puede hacer 118 +Acesse 111 +¡Hé 111 +¡Fast 111 +Estranjo 111 +¡Dios 111 +¿Tú 111 +¿Bien 110 +Pero 102 +Presidente 101 +Estudio 101 +¿Cuánto 100 +ver el video 98 +en contra 97 +favor 92 +presidenta 90 +A favor 89 +¡Garante 89 +¡Fossil 89 +¡Gazán 89 +Llegué 89 +¿Qué opinión 89 +¡Aquí 89 +¡Germano 89 +¡Hasta luego 89 +¡Mamá 89 +y el objetivo 88 +Convergencia 88 +Gracias por ver el vídeo 86 +¡Ay 85 +votación 78 +¿Puedo ver 77 +Salini 77 +Ah, no 75 +¿Dónde está 74 +Bueno 73 +gracias 73 +Salim Daffi 73 +¿A favor 72 +¿Termin 72 +señora presidenta 70 +¡Viva la vida 68 +estratégico 66 +¿Qué es lo que se llama 65 +Señor Singen 64 +de 63 +Adelante 63 +también 63 +¡G-I-S 63 +L'anquistad 63 +¿Qué documentos presentan 61 +¡Puedo votar 61 +¿Están bien 61 +¿Puedo pasar 59 +Boni 59 +¿Ahora es 59 +tamboy en cuenta 59 +más 58 +¿Cómo conocen los derechos 58 +¡Nos vemos 57 +También 54 +¡A un momento 54 +rechazada 53 +¿Qué es 53 +Gracias, señor Gualtieri 53 +contra 52 +Pues 52 +Luz de Besa 52 +¿Qué onda 51 +Salas 51 diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/et.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/et.txt new file mode 100644 index 00000000..0fd9a0ec --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/et.txt @@ -0,0 +1,281 @@ +Kõik 1718177 +Kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 31943 +Kõige 7729 +Kiitos 4342 +See 3830 +Paldies 3448 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 1836 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 1819 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 1791 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 1787 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 1779 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 1750 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 1523 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 1521 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 1489 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 1368 +Aitäh 1321 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 1261 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 1156 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 1043 +Kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on 998 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 845 +Kõik on kõik 817 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 778 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 710 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 669 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 617 +Kõik teht 565 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 541 +Kõik te 488 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 451 +Kult 448 +Kõik tehtu 402 +Ja 400 +Kõik teemad 368 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 362 +Eks minuut 356 +Kõik see 351 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 346 +Kastu 327 +Eee 307 +Kõikus 298 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 286 +Kõik sa 271 +Kõikult 262 +Kõik on tehtu 256 +et 252 +Kõik teist 238 +Eh 238 +Paldun 231 +Gu 222 +Eita 219 +Hõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõ 217 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 213 +Eta 208 +Kõik teed 207 +Kõik se 206 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 201 +Hvala 195 +Kolegit 175 +kõik 174 +Pult 166 +Kõik on 162 +Kõik sõnud 157 +Kui 155 +Ees 154 +Eit 153 +Kost 151 +Leks 149 +Eme 149 +Eel 149 +Eur 149 +Paz 148 +Armet 148 +Eto 148 +Kust 148 +Agust 148 +Kõne 148 +Erit 148 +Arine 148 +Kies 148 +Elu 147 +Kõik teha 146 +Eks 146 +Eri 146 +Arame 146 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 142 +Et 141 +Asena 140 +Ena 140 +on 136 +Kola 135 +Mõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõõ 133 +Kus 131 +Küsimus 130 +Kõrge 129 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 117 +Euroopas 115 +Ehti 113 +Korda 113 +Puhul 112 +Eriti 111 +Kavad 111 +Katoch 111 +Kovosa 111 +Eelta 111 +Kõsel 111 +Kiasal 111 +Kärst 111 +Kulik 111 +Eronomi 111 +Kostol 111 +Pallona 111 +Päst 111 +Aitah 110 +Üldse 110 +Kondi 110 +Kusk 110 +Aitoma 110 +Eurist 110 +Arandusi 110 +Araneb 110 +Kisek 109 +Evalik 109 +Eelü 109 +Eegis 108 +Kuhul 107 +Paldaks 106 +ja 105 +Lepool 104 +EUROT 102 +Kosoval 101 +kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on 95 +kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on 93 +on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on 93 +Kõik teembril 92 +Eesti 92 +Kõik on teemad 91 +Põnud 91 +Kõiklo 89 +Kandahal 89 +Eerikia 89 +Kõpsel 89 +Kesturel 89 +Kõrki 89 +Eest agist 88 +Puiustel 88 +Nõnud 88 +Kadeskos 88 +Armeenia 88 +Eremiseks 88 +Aastumine 88 +Kulitsus 88 +Kõhul 88 +Kratlikult 88 +Katsioon 88 +Põhul 88 +kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on 87 +Kõigele 87 +Eelikult 87 +Kõigal 86 +Ning 85 +on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on 85 +Võimine 85 +Kõik on sõnud 84 +Kainvies 84 +Kõnasa 83 +kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on 82 +Kõnast 82 +kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on 81 +Kõik võit 80 +Kõrta no 80 +Kõik osa 79 +on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on 78 +Kõikame 78 +Tõnus 77 +Kärver 77 +Kõik tehti 76 +Kest pavad 74 +Kõik mees 74 +Eriti zeta 74 +Kõnalea 74 +Hada loodsch 74 +Hvala presidenti 74 +Kõik seda 74 +Kõik meeld 74 +Hea meel 73 +Eri oskusi 73 +Kõigelema 73 +Kõik on 26 73 +Kõiksteist 73 +Kulingrege 73 +Nõel 73 +Eitreikel 73 +Suuradu 73 +Lõppanud 73 +Kõik jist 73 +on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on 72 +Kõige pealt 72 +Kõik on tehtud 72 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 70 +Sõdano 70 +Klaabe niht 68 +Kärvost 68 +Põlod 67 +Kvies 67 +Kõikides 67 +Kõhra 67 +Korda no 66 +Kõu 66 +Kõikile 65 +Kõneks 65 +See on 64 +Kõikinsa 64 +Pavel 64 +Eeg 84 64 +Aga 63 +kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik kõik 63 +Kõik jubel 63 +Kõik sest 63 +Kõikabelt 63 +Krasnobetski 62 +Kõik teulad 62 +Kõik teada 62 +Kõik te luga 62 +Põhjus 61 +Kõik net 61 +Kõrl 61 +Häära 61 +Eeg 61 +on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on 60 +Kõik teile 60 +Era poolehtu 60 +Kõik tex 60 +Kolega Rinaldi 60 +Eks valmis 60 +on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on 58 +Kõik siis 58 +Hvala prezident 58 +Arasimseli 58 +kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on 56 +Sorda, no 56 +Kõik pala 56 +Siis 55 +Pätsednitse 55 +Kõik minu 55 +Kõik jasad 55 +Kõrsteid 55 +Küsimusas 55 +on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on 54 +Aastatud 54 +Kõik aastal 54 +Eletrooniliselt 54 +Eemidega 54 +Kiste puhkudel 54 +Koolaeg 54 +Kõik tehtivist 54 +Eeglite alusel 54 +Kõik meadvise 53 +Kõik on pult 53 +Lõppinud 53 +Kõikultasandel 53 +Tõepärast 53 +Elga 53 +Kustatama 53 +Kõik te seda 53 +Kõik võttu 53 +Põrtele 53 +vastu 52 +ka 52 +Kõik fläna 52 +Kõik me tehtik 52 +Kõrda 52 +Vastu 51 +on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on kõik on 51 +Kõik teemise 51 +Kõik on vastu 51 +Kõik on 80 51 +Eilonsa 51 +Eitsa 51 +Kõik lõst 51 diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/fi.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/fi.txt new file mode 100644 index 00000000..9eee81c9 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/fi.txt @@ -0,0 +1,2 @@ +Kiitos 9048 +Kiitos, minä 52 diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/fr.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/fr.txt new file mode 100644 index 00000000..f386ee44 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/fr.txt @@ -0,0 +1,156 @@ +Sous-titrage Société Radio-Canada 150783 +Merci 79917 +le Président, M 17491 +Je remercie 7395 +Je vous remercie 2838 +le Président et M 2650 +Au revoir 1395 +le Président 1129 +Merci d'avoir regardé cette vidéo 1066 +Sécurité 1053 +Oui 1020 +Merci à vous 886 +Merci, M 841 +Un 663 +Merci à mes Tipeurs et souscripteurs 650 +Pour 527 +Contre 485 +Bien 476 +Hum 447 +C'est bon 412 +Merci à tous 403 +Amen 383 +S'il vous plaît 368 +Société Radio-Canada 334 +Non 301 +Et 299 +pour 277 +Bon 269 +Pardon 238 +Les 232 +On 224 +Sur 223 +Bite 222 +Des 222 +Nature 222 +Par 222 +En 222 +Dieu 216 +Hop 214 +Point 212 +du 211 +Surtout 208 +Le vote est ouvert 207 +Abstention 196 +C'est ça 194 +Sous-titrage FR Pays de l'Ontario 157 +Bon appétit 150 +Ambition 148 +Très 148 +Lé 148 +Évaluation 147 +le Président, et M 147 +le M 147 +SED 145 +S1 144 +Madame la Présidente 143 +Ré 143 +Sip 143 +le 142 +C'est un problème 141 +Trois 140 +L3 140 +Sari 140 +Le 10 139 +Le M 136 +Je vous remercie, M 133 +que 132 +Alors 131 +contre 130 +Donc 125 +Mais 124 +Sérieux 113 +et 112 +Sincère 111 +Satellite 111 +Ressources 110 +Évolution 110 +Surgir 110 +Rassurer 110 +Mille place 109 +Jury 6 109 +Le gouvernement 4 109 +C'est un peu comme ça 108 +Yurek 108 +Munger 108 +Je ne sais pas 106 +Bonsoir 106 +Sorsion 101 +C'est quoi 100 +Sérielle 99 +C'est un 92 +Sénophine 89 +L'association 89 +procédure 89 +Gratulièrement 89 +Merci beaucoup 88 +Sondement 11 88 +L'esprit 87 +législation 87 +Kaut, M 87 +Président, M 84 +Compromis 84 +Voilà 83 +Adopté 82 +C'est ce que je veux dire 82 +Je m'en 82 +Légalité 81 +L'organisation 80 +Alphonsi 79 +discrimination 78 +Radio-Canada 77 +C'est génial 75 +Le logement 75 +Évaluations 75 +Le phosyte 74 +Kelly, M 74 +Bleu 74 +Sources de croissance 73 +L'adhésion 73 +C'est pas ça 72 +C'est pas grave 72 +Leynan, M 72 +A, B, T 72 +Pendeja 72 +47 71 +Le 5 70 +Salut 68 +Garner, M 67 +Le microproche 67 +L'éducation 65 +adopter 64 +SIGURITÉS 63 +le Président, 62 +Zorvaman, M 62 +Bonjour 62 +L'Asie centrale 62 +Brock, M 61 +Ensuite 60 +Durablement 60 +qui 59 +C'est moi 59 +Exploration 58 +questions 56 +Monde-monde 56 +Sra 55 +Engel, M 55 +Quatorze qui est pour 54 +Swinburne 54 +C'est pas illégal 54 +Claire 53 +On peut trouver d'autres personnes 53 +de 52 +Le centre adopté 52 +C'est parti 51 +Adoptez 51 +Gerdinger, M 51 diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/hr.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/hr.txt new file mode 100644 index 00000000..5bc598dd --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/hr.txt @@ -0,0 +1,88 @@ +Hvala što pratite kanal 146783 +Hvala vam 13292 +Hvala 7568 +što pratite kanal 2739 +Hvala što pratite 2366 +pratite kanal 2018 +Hvala vam na sviđanju 1847 +Hvala vam se 1706 +kanal 1673 +Hvala na sviđanju 1653 +Sviđa 1010 +10 668 +Hvala se 613 +Da 555 +Hvala vam na sviđanje 362 +Uvijek 335 +Ne 305 +vam 253 +Hvala vam sviđanje 233 +Pa 226 +30 225 +Text 223 +2019 222 +16 219 +Hrana 213 +Sviđanje 212 +109 165 +Lama 147 +Sto 146 +Hrvatska 145 +Hvala ljepo 141 +Hvala lijeva 128 +Ďakujem 125 +Let's go 111 +Lepo 110 +Hvalit 110 +Hvala pa 99 +Hvala li 93 +Hvala ne pa 92 +Ljubam 89 +Oprostili 89 +Odbora 9 88 +Lijepa 88 +Hvijek 87 +Vot is open 86 +Misije 85 +Hvala se ni 82 +Hranih 82 +se 79 +Hvala li je pa 79 +Hvala vam glasovanje 76 +Odbija se 75 +Hrvatsko 75 +Hvala novi 74 +Hvala lepa 74 +Sviđate 74 +Hvala imamo 74 +Hvala, Obama 74 +Hrvatski 74 +Top 10 najboljih uvijek 73 +Hvala mi se 73 +Hrvatsko je uvijek 72 +Hvala nič 71 +Hvala reč 69 +Ali 67 +Hvala vam ljepo 67 +Hvala na sviđanje 66 +Stabilnosti 65 +Hrvodnu 64 +Protiv 63 +Hvala za žene 62 +Top 10 minuten 62 +Hrvatskama 62 +Sviđa se 62 +Hvala Lepan 62 +Hrvodin Peters 62 +Dođer 61 +Hvala vam ljepa 61 +Zatvaram 60 +Hvala vam sviđanju 58 +Hvala o 55 +Okupaciju 54 +Hvala djepa 54 +Hrvatsko na to 54 +Peti 54 +Hvala, Sonja 53 +Hvala še stok 53 +Hvala komisji 53 diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/hu.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/hu.txt new file mode 100644 index 00000000..c42536be --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/hu.txt @@ -0,0 +1,116 @@ +NAMASTE 149324 +Köszönöm 26109 +Köszönöm szépen 24607 +Ha 1987 +Köszönöm, hogy megnézted 1827 +szépen 862 +Ha tetszett 757 +Köszönjük 742 +Nem 640 +Egy 505 +És 326 +Oké 321 +Rendben 295 +Szó 294 +Ellene 282 +megnézted 281 +Hogy 276 +Szóval 258 +Elena 252 +Eléna 247 +Csak 242 +Az 233 +Eléne 224 +A köszönöm szépen 223 +Mag 213 +hogy 210 +Szóra 205 +és 200 +Köszönöm, hogy megtaláltad 163 +Köszönöm, M 160 +Azt 157 +Szeg 150 +Elen 149 +Pán 148 +KZ 148 +Azal 148 +Szükség 148 +Azaz 148 +Szig 148 +Magari 147 +Szia 147 +Mikrok 143 +Rá 140 +Ipar 139 +Ná 132 +A mi 124 +Elenor 115 +A lát 111 +Róra 111 +Kérem 110 +Szépen 110 +Szitva 110 +Egyen 108 +Kétes 107 +úr 102 +Rógy 102 +Ha tetszett, ha tetszett 101 +99-2 101 +Ne 100 +Áj 95 +is 90 +Ellen 90 +zárom 90 +Szangosz 89 +Évő 89 +Elégete 89 +Rászol 89 +Már Fát 88 +Lanzi K 88 +Bevétel 88 +Elnöck 88 +Igy marad 88 +A sány 87 +Fájt 87 +Néhá 85 +Előne 83 +Elő 81 +asszony 77 +Én 76 +Ból 76 +De 74 +A oitúr 74 +Elfogottuk 74 +Szolgának 74 +Kárcúr 73 +Szabályok 73 +dé hát 73 +Néhána 72 +Hátorikán 72 +54 72 +Pag 72 +Egyesel 71 +Agyébben 70 +A gájom 70 +Akkor 68 +Először 65 +Elécte 64 +A MEO 64 +Egyényesk 62 +Bármát úr 62 +Kifal elastei 62 +Magyar 61 +Mindenkételő 60 +Magyarországon 59 +Szávazónk 58 +Négy százal 57 +Köszönöm, köszönöm 56 +Ön 56 +A megyet 56 +A Vényassó 55 +Azta 54 +Egy élete 54 +Szentemátor úr 54 +van 52 +Néződani 51 +Képviselők 51 diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/it.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/it.txt new file mode 100644 index 00000000..3aa936b7 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/it.txt @@ -0,0 +1,9 @@ +Grazie mille 952 +Grazie 918 +Grazie a tutti 244 +Chi è a favore 133 +Compromesso 10 105 +Perchè 72 +grazie 65 +La votazione è aperta 61 +mille 54 diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/lt.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/lt.txt new file mode 100644 index 00000000..45b7f663 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/lt.txt @@ -0,0 +1,431 @@ +Dėkis 121685 +Paldies 111274 +Pag 49533 +Dabarėjau 26965 +Ačiū 22517 +Ir 18466 +Dėkis, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 15058 +Taip 14221 +Ar 12382 +Dabarėjimu 10643 +Tai 6677 +Ďakujem 6574 +Aš 5109 +Labai 3331 +Dabarėjome 2541 +– Dėkis 2516 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 2461 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 2425 +Dabarėjus 2371 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 2302 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 2288 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 2270 +Dabarėjimą 2253 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 2244 +Taip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, 2188 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 2152 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 1981 +Bet 1841 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 1786 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 1591 +Dabar 1487 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 1368 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 1289 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 1176 +At 1115 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 1023 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 1022 +Įdėjimu 1008 +Nu 910 +Arba 906 +Dėkodės 864 +Labas 857 +Įdėkis 823 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 823 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 820 +Tačiau 789 +Nes 772 +Taip, taip 763 +Nė 758 +Mūsų 741 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 711 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 696 +at 678 +Ačiūrėjau 663 +Dabarėjame 646 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 582 +Gerai 572 +Čiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiausiaus 568 +Aplodinės 512 +Sėdėkis 480 +Taipos 479 +Su 477 +Arbus 444 +Arčio 437 +Sėkiai 430 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 427 +Šiandienas 375 +Tai yra 364 +Atsiū 354 +Dėkštie 350 +Dabarėjimai 318 +Iki 318 +Žinoma 306 +Aras 296 +Įdėjame 292 +Nei 292 +Sėkmės 291 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 288 +Arvo 286 +Čia 284 +Pagliau 280 +Dabarė 261 +Anto 258 +Kėdėkis 242 +Tu 234 +su 233 +Te 230 +Ačiu 229 +Dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis 228 +Sėkodės 227 +Nėra 226 +13 223 +Gru 222 +Ar mums 222 +Betis 221 +Arčiu 218 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 214 +Ir Ir 206 +Įsta 192 +Šiandien 192 +Čiausiai 188 +Mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų 185 +Prieš 167 +ir 165 +Sama 163 +Dabar mūsų 161 +Arėjus 161 +Dėkui 160 +Taigi 160 +Įdėjim 157 +Sė 156 +Dėkite 155 +Aki 155 +Tama 155 +kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, 154 +Ehm 154 +Vy 153 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 152 +kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, 151 +Nato 151 +Yra 151 +Antra 151 +R2 150 +Aroma 150 +Labie 150 +Asta 150 +Pum 149 +Armas 149 +Imo 149 +Irma 149 +Arman 148 +Kli 148 +Serio 148 +Kali 148 +Arif 148 +Avas 148 +Ina 148 +Aps 148 +Betro 148 +Aris 148 +Antios 148 +Rol 148 +Tux 148 +Iba 147 +Tant 147 +Atra 147 +Antras 146 +Arline 145 +Sėmės 143 +Dabarės 143 +Ačiūrėjus 143 +Dėkodis 141 +Beb 141 +Naudoklis 140 +Labra 139 +Ir mūsų 139 +Argo 139 +Dž 138 +Dabarysi 138 +Laki 138 +Rai 137 +Tiba 137 +Hr 137 +Torbu 136 +Taile 136 +Ir jūsų 136 +Ante 135 +Atia 134 +Sėkės 134 +PC1 134 +Mės 133 +Jūsų 133 +Na 130 +Iks 130 +kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, 128 +Ar jūsų 128 +kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, 126 +kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, 126 +Sės 124 +kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, 123 +Taip, taip, taip 123 +Ačiškia 122 +kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, 121 +kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, 120 +Dėkia 118 +Daugiau 118 +Ar to 118 +dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis 117 +kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, 115 +Są to 114 +dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis 112 +Arsulo 111 +Ir ponios 111 +Irmant 111 +TITIA 111 +Armanso 111 +Akti 111 +Manžia 111 +Ardus 111 +Pabies 111 +Ir gana 111 +Če 111 +Buhata 110 +Mėdėkis 110 +Aši 110 +Kulose 110 +Arceos 110 +Antekste 110 +Irranga 110 +Eurų 110 +Tūra 110 +Irritant 110 +Arminija 110 +Tinkas 110 +Eurot 110 +Pana 30 109 +ďakujem 109 +Įdu 109 +dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis 108 +Lepas 107 +Tai lū 106 +Dėkos 105 +Aisnes 105 +Mančila 104 +Konec 103 +Aspecti 103 +Ir buvo 103 +kad 101 +Dėl 101 +0, 1 101 +dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis 100 +Ar visi 97 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 96 +Ir moji 95 +Ikias 94 +Paldiesi 94 +dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis 91 +dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis 90 +Tėkis 90 +Mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų mūsų 89 +Sėkro 89 +Atsenau 89 +Aristo Poli 89 +Atsukė 89 +Siv 89 +Ateikia 89 +Dabarba 89 +Irminkė 88 +Arvojame 88 +Atsargas 88 +Ačiup 88 +Kliantų 88 +Išdus 88 +Aš manau 88 +Totojui 88 +Irskova 88 +Išdava 88 +Antizacija 88 +Aikėti 88 +Ačioms 87 +ČNES 87 +Dėmato 87 +Aštas 87 +Arbačiu 87 +Konfliktus 87 +kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, 86 +kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, 86 +16 86 +Sąčiu 86 +Įdėjau 85 +Apsauka 85 +Sėrtu 85 +Pats yra 83 +Arpiai 83 +Dėkai 82 +Aštė 82 +Kas už 81 +Rekas 80 +Ačiūrėjimu 79 +Matša 79 +Ietimas 78 +Aplodis 77 +Dėkis kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės kėdės 77 +kur 77 +Apskite 77 +Taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, taip, 76 +Taipa 76 +Ďakujem, į reikiausiai 76 +dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis 75 +Kad 75 +Tumar 75 +Dabar komis 74 +Vėliau 74 +Ar mūsų 74 +Lėčių 74 +Raišin 2020 74 +Naftaliu 74 +Kotecikia 74 +Irpanašė 74 +Ostatusą 74 +Atojau 74 +Dėkodas 73 +Omenyės 73 +Kulbės 73 +Arnekaimu 73 +Eishkinti 73 +Arėmės 73 +Atsiči 73 +Aštinti 73 +Atsuosime 73 +Dabūksta 73 +Pa 72 +Palsuojame 72 +Aškačiu 72 +Atsauktas 72 +Tadarita 71 +Sėdėjau 71 +Dėklau 71 +Aš reikia 71 +Šmėdė 71 +dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis 70 +Aizdota 70 +Atsaukite 70 +Egoizmo 70 +Rūtas 70 +Mės trą 70 +Aplaukite 70 +Aš ką 69 +O, beaciu 69 +Ar teklūs 68 +pirmininkė 66 +PAS 66 +apie 66 +Įdėkite į vietą 66 +Aš čia 66 +Tadėta 66 +O, nė 66 +Dabarėjai 65 +už 65 +At lo 65 +Gerbimie 65 +Yponijų 65 +Irtepad 65 +Kaip 64 +Argus 64 +Kojo 64 +PRAŠAM 64 +Vėlės nuo 63 +Pagėmės 63 +Paginacijos 63 +Latinos 63 +Paneugus 63 +Aš nesitama 63 +kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, 62 +Bezauwite 62 +Taipas 62 +Sėlėkis 62 +Šukšlivena 62 +Oskokybę 62 +Tūs taas 62 +Tau reakiai 62 +dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis, dėkis 61 +Įdėjus 61 +Rekštokat 61 +Sėlėtus 61 +Ar dveja 61 +Ačiūsiu 61 +Dėkis doma 61 +Atsipračiu 61 +Tėlička 61 +Antonia 61 +Aštumto 60 +mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų 60 +Dėkis turi 60 +Paglėtis 60 +Ar tiju 60 +Vėlųjų 60 +Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir Ir 59 +kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kuris, kur 59 +Mūsų ats 59 +Rādžiai 59 +Europartnerista 59 +Dėkštė 59 +mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų 58 +Sėstis 58 +Dėkite pras 58 +Ažvilgiu 58 +Įdėjie 58 +Apsaugos 58 +Aitėtus 58 +Štėdė 58 +Atsakyti 57 +Dėkis toks 57 +Aš kėsų 57 +Tausiai 56 +Kas prieš 56 +Ačiū, pirmininkė 56 +mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų 56 +Sėdėjimu 56 +Pėdėjau 56 +Mas 55 +Dabarėjim 55 +Paglėjimu 55 +Dėkis sektori 55 +Rinkoasteliją 55 +Arslinkus 55 +Są poteštę 55 +mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų 54 +Tačiūrėte 54 +Šeitai 54 +Martheu 54 +Aš Karolissi 54 +Sėmėrės 54 +Sėkėjimu 54 +Žinoma rengini 54 +mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų, mūsų 53 +Arčiomario 53 +Sėlėnės 53 +Ir laisvimus 53 +kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, kaip, 52 +Aristo poli 52 +Pai sėkės 52 +Ar kitur 52 +Ir tvingumo 52 +Dėkodėjome 52 +Atsigiams du 52 +Grazie 51 +– Sėdėkis 51 +Nielsonas 51 +Tato sūbėra 51 +Atitikia ma 51 diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/lv.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/lv.txt new file mode 100644 index 00000000..9f77252d --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/lv.txt @@ -0,0 +1,2 @@ +Paldies 3222 +Plāksmē 64 diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/mt.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/mt.txt new file mode 100644 index 00000000..79a3dc61 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/mt.txt @@ -0,0 +1,150 @@ +Ďakujem 9190 +Hvala što pratite kanal 6349 +NĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚ� 2605 +Hvala što pratite 2486 +Għħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħ� 1561 +Hvala 1404 +Paldies 668 +30 668 +Grazie 595 +000 447 +10 445 +Hrķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķķ 404 +Hãy subscribe cho kênh Ghiền Mì Gõ Để không bỏ lỡ những video hấp dẫn 331 +President 322 +għħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħ� 311 +Sra 304 +Hvala še 299 +Dż 293 +20 227 +19 221 +Issa 168 +Ehm 165 +Contra 157 +Hvala što 153 +Lili 150 +Horm 150 +Sari 149 +Zer 149 +Tzu 149 +Sene 148 +Nala 148 +Beş 148 +Sala 148 +Nati 148 +goni 148 +Juss 148 +Siti 148 +Eri 148 +Pus 148 +Tog 148 +Suur 147 +Paro 146 +Hru 146 +Alissa 145 +Signora 144 +Nya 143 +Pag 143 +Ritz 141 +Ski 140 +Simp 139 +Tuha 136 +Hvala š 127 +Egu 127 +Hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, 119 +Taddi 118 +Haffner 114 +Hrani 113 +Konec 113 +Kodin 111 +Bu tako 111 +U fó 111 +Če 111 +Lessa mis 111 +Kosovo 111 +Esteren 111 +deals 111 +Nāru 111 +Nitsha 111 +Tukun 111 +Mazzini 110 +Lawa net 110 +Hrsh 110 +Nolos 110 +Ponsi 110 +Grazzi 109 +30-1 108 +Apoš 107 +Dossier 103 +Hãy subscribe cho kênh Gõ Để không bỏ lỡ những video hấp dẫn 103 +Naisna 102 +Natsura 102 +Doan 96 +N-net 92 +Hr 91 +Hvala ki 89 +Prego Pilar 89 +Eriksie 89 +Hrviti 89 +Senora Bowles 89 +Hvala vam 89 +Nsiebo 89 +Buat malo 89 +Hrāti 89 +Nil-a 88 +Katsafna 88 +R-Russia 87 +Hjajan 87 +Dżuara 86 +hafna 83 +Čo 82 +Āhna 77 +Hrvatsi għu 76 +Sada 75 +Tore vi melo 74 +Zekunniku 74 +Smaq 74 +Hvala abit 74 +Zipan, Jersey 74 +Gįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįį� 73 +N-adjus 73 +Tafna lom 73 +Nishteħ 72 +Lewa l-net 72 +O emmenu 71 +Hvala i ne 71 +Hrvatski 70 +Għraċi 68 +Trican, mile 68 +Hvala što prat 66 +Is for me 66 +Īvan 66 +Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za Ďakujem za 63 +Čnāla 63 +N-u kontra 63 +Nes rots opa 63 +TZBI don't understand 63 +Hvala i tada 63 +Mr 62 +gįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįįį� 62 +EF-E-U 62 +Hrundan aminto 62 +Representa me 61 +Hrvatskaj 61 +minuta 60 +Welp 60 +So nice to see you 59 +Tulli-s min 59 +Sera Sera Président 55 +Hrubitikofa 55 +Hvala sko zain 55 +Hvala što pratiti 55 +Alman d'Ažer 55 +Atención que se requiere 54 +Čnđe 53 +Graċi 52 +Isimu 52 +Hr-Rush 52 +illi 51 +Sürmetsalikaj 51 +Čina 51 diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/nl.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/nl.txt new file mode 100644 index 00000000..c562d1b8 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/nl.txt @@ -0,0 +1,5 @@ +Dank u wel 123 +wel 87 +Kompromis 4 86 +Nr 72 +Kompromis 4a 63 diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/pl.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/pl.txt new file mode 100644 index 00000000..0e5e2643 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/pl.txt @@ -0,0 +1,10 @@ +Dziękuję 778 +Dzień dobry 299 +Kto jest za 131 +Dziękuję bardzo 121 +Kto się wstrzymał 114 +Sześć 91 +Kto przeciw 88 +Kompromis 13 88 +Kto jest przeciw 71 +Dziękuję za uwagę 55 diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/pt.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/pt.txt new file mode 100644 index 00000000..c2c3cbef --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/pt.txt @@ -0,0 +1,27 @@ +Sra 8711 +Presidente 1486 +Sr 1435 +Obrigada 1148 +Presidente, Sr 761 +Obrigado 619 +Obrigada, Sra 520 +Obrigado, Sr 370 +Obrigada, Sr 349 +Já 201 +Muito obrigada 168 +Enf 135 +Srs 123 +Muito obrigado 109 +Com licença 105 +800, 1 85 +Renda, Sr 75 +Diz, Sr 72 +Presidente, o Sr 68 +Presidente, Sra 67 +Cavada 66 +Svab 64 +Contra 63 +Abstenções 59 +Martins 57 +O que é a reunião 55 +Jouvin, o Sr 52 diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/ro.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/ro.txt new file mode 100644 index 00000000..047d3dc3 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/ro.txt @@ -0,0 +1,285 @@ +Să vă mulțumim pentru vizionare 64103 +MULȚUMIT PENTRU VIZIONARE 47032 +La revedere 44575 +Să ne vedem la următoarea mea rețetă 32817 +Mulțumesc 26905 +Nu uitați să distribuiți acest material video pe alte rețele sociale 12082 +Mersi 8073 +Nu uitați să dați like, să lăsați un comentariu și să distribuiți acest material video pe alte rețele sociale 5936 +Mulțumesc frumos 3477 +pentru vizionare 2347 +vizionare 2079 +Nu 1586 +mulțumim pentru vizionare 1148 +Să vă mulțumesc frumos 1048 +rețetă 1018 +Să lăsați un comentariu și să distribuiți acest material video pe alte rețele sociale 1008 +Mulțumim 968 +Să 927 +în 893 +Mulțumesc pentru vizionare 766 +cu 738 +S-a deschis votul 704 +Aș 655 +Să vă mulțumesc pentru vizionare 632 +Mersc 589 +mea rețetă 526 +Da 504 +S-a închis votul 475 +Sărbătoare 468 +Este 458 +un 456 +Spins 434 +Nu uitați să dați like, să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu 420 +următoarea mea rețetă 404 +Să ne vedem în următoarea mea rețetă 387 +Bun 356 +Așa 353 +Nu uitați să vă mulțumim pentru vizionare 350 +Să vă mulțumim 336 +vă mulțumim pentru vizionare 333 +Succes 332 +Sankies 328 +Să nu 324 +Să vizionare 322 +Mă 308 +și 307 +Clare 297 +alte rețele sociale 296 +Sine 296 +pe alte rețele sociale 291 +VIZIONARE 271 +Pentru 270 +rețele sociale 252 +sociale 251 +material video pe alte rețele sociale 251 +Să vă mulțumesc 251 +vedem la următoarea mea rețetă 241 +pentru 240 +video pe alte rețele sociale 239 +Mersk 235 +Nu uitați să dați like, să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați 233 +ne vedem la următoarea mea rețetă 230 +Muzica 227 +Un 226 +Ar 224 +Sără 222 +Sfântului 222 +Financiare 222 +Săr 220 +Victor 220 +acest material video pe alte rețele sociale 216 +Muzică 199 +la următoarea mea rețetă 197 +distribuiți acest material video pe alte rețele sociale 185 +Să deschis votul 185 +Măsuri 176 +Sfântul 175 +să distribuiți acest material video pe alte rețele sociale 168 +Nu uitați să dați like, să distribuiți acest material video pe alte rețele sociale 161 +Acord 157 +sigur 156 +Nu uitați să vă mulțumesc pentru vizionare 153 +Adios 153 +Mers 151 +Vă mulțumim pentru vizionare 151 +Mica 150 +Vitor 150 +Energia 149 +și să distribuiți acest material video pe alte rețele sociale 148 +Schimb 148 +Mies 148 +Astro 148 +Estico 148 +Conturi 148 +Conte 148 +Sina 148 +Azo 148 +Suta 148 +Spania 148 +Ski 148 +Redus 148 +IMP 148 +Sins 148 +Lucie 148 +Iana 147 +Ieri 147 +SDI 147 +Să mai departe 146 +Sper 146 +Trei 145 +Odii 145 +Mim 144 +Bras 143 +că 140 +Martín 140 +Vă mulțumesc pentru vizionare 136 +Sala 134 +Sărbă 133 +și să lăsați un comentariu 132 +Nu uitați să dați like, să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu 129 +Apoi 128 +Tiza 127 +Și 124 +Să deschideți 124 +Svotovske 124 +Nu uitați să dați like, să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu 120 +Adopta 120 +Spera 120 +PENTRU VIZIONARE 113 +Sperți 112 +Tronice 111 +Irlandese 111 +MdG 111 +Miemo 111 +Mieți 111 +MENI 111 +Spasca 111 +Métie 111 +HACP 110 +Hora 15 110 +Ilegale 110 +Vod electronic 110 +Dreptur 110 +Sărit 110 +Bunzitor 109 +Măsc 108 +Sankiz 108 +Muzora 108 +Să vă mulțumesc pentru like, să lăsați un comentariu și să distribuiți acest material video pe alte rețele sociale 107 +Sankt 107 +Sfie 107 +Căr 104 +Să ne vedem la urmă 103 +Exemplu 103 +Sperte 103 +Ruta 79 103 +care 102 +şi 102 +lăsați un comentariu și să distribuiți acest material video pe alte rețele sociale 101 +Rău 92 +uitați să dați like, să lăsați un comentariu și să distribuiți acest material video pe alte rețele sociale 91 +Sărdo 89 +Măiți 89 +Ouropeine 89 +URGENTE 89 +Excesivă 88 +Mulgherini 88 +The vote is closed 88 +Exționat 88 +Succesul 88 +Să bine 88 +BASEL 3 87 +Votul 5 87 +Sfotul 87 +Aptineri 87 +Sank is vătul 87 +Mătul 87 +Acest lucru 86 +SIGLAIN 86 +Aptinari 85 +Răspuns 85 +Sărace 84 +Sărcere 84 +Mă mulțumim pentru vizionare 83 +Mulțumesc, domnule președinte 81 +Să spune 81 +Luhurul 81 +un comentariu și să distribuiți acest material video pe alte rețele sociale 80 +Să deschia zvătul 80 +Răspins 79 +Mulțumesc, președinte 78 +Suntul 10 77 +Cuquina 77 +S-Li 76 +Abținari 76 +S-a adoptat 74 +Merskviki 74 +Hacem regulament 74 +Dar 73 +Sfășara 73 +Sfără 73 +Sfăruri 73 +Să deschise 73 +S-PONS 73 +Compromisul 1 73 +Sinc de votul 73 +Sancis votul 73 +S pentru 73 +Contrastrategie 73 +Sankis votul 73 +Sărunga 73 +uitați să distribuiți acest material video pe alte rețele sociale 72 +Să remarcăm 72 +Muzurilor 72 +Nu uitați să dați like, să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu 71 +Să închis 71 +Răgurile 71 +Odgovița 71 +Așteptăm 70 +votul 70 +Să ne vedem la următoare 69 +Sfânta 69 +Doamne 68 +Mulțumim pentru vizionare 68 +Nu uitați să dați like, să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu 66 +comentariu și să distribuiți acest material video pe alte rețele sociale 66 +Sănkis votul 66 +Votrn 66 +Sărcum 66 +Să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lăsați un comentariu și să lă 65 +Ar vanitist 65 +Vătul 65 +Trăiști 65 +like, să lăsați un comentariu și să distribuiți acest material video pe alte rețele sociale 64 +Nu-am 64 +să lăsați un comentariu și să distribuiți acest material video pe alte rețele sociale 63 +Sfântul 23 63 +Sfântul 83 62 +Să gândiți 62 +Sfântul 76 62 +Să te urziu 62 +dați like, să lăsați un comentariu și să distribuiți acest material video pe alte rețele sociale 61 +să dați like, să lăsați un comentariu și să distribuiți acest material video pe alte rețele sociale 61 +S-a închis 61 +Mă-Covei 61 +Sfântul 24 61 +Sfântul European 61 +Sfie folosita 60 +Să lăsă 60 +de 59 +Să ne vedem 57 +Să ne ajutăm 57 +Să ne spingă 56 +Fissas 56 +Sărbăr 56 +Sfântul 11 56 +președinte 55 +Bună 55 +Mă rețința 55 +Vărgânta 55 +Mă testaţi 55 +Aplicați-vă 55 +adoptă 54 +De ce vile 54 +Sistă-mă 54 +Suntem vorbitori 54 +Să deschise votul 54 +Om 54 +Să răspundi 54 +MIGA 54 +Să închim votul 54 +Pălamentarea rurală 54 +Sfântului 2020 54 +Sama frunzulica 54 +Să înkis votul 54 +Să gizvotul 54 +Să sunt întrebări 54 +Ia cuvântul 54 +Să gisvotul 53 +S-a sublinieze 53 +Sărbădă 52 +Din Belarus 51 +Sunt pentru 51 +S-a deschis vot 51 +Sărbătate 51 diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/sk.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/sk.txt new file mode 100644 index 00000000..4b0a8446 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/sk.txt @@ -0,0 +1,83 @@ +Ďakujem za pozornosť 1645498 +Ďakujem 125315 +Ďakuj 40009 +za pozornosť 9407 +pozornosť 9382 +Konec 2653 +Zdravíte 567 +Pre 443 +Hvala 440 +OSN 296 +Kov 295 +Hr 292 +Hru 287 +Ale 286 +Čau 268 +za 236 +1% 223 +Cent 222 +Od 222 +10 219 +že 217 +Máša 167 +Zdravíme 163 +Hvala mi 151 +Per cent 149 +Sonny 148 +Hoh 147 +Kult 147 +MF 146 +Salde 145 +Kto je za 144 +Sala 143 +zi 140 +Proti 139 +Osem 139 +108 135 +Percent 133 +Hvala za pozornosť 131 +Že 119 +Zdra 112 +Odgaard 111 +Ús 111 +Kostel 110 +Hapel 110 +Kvim 101 +Hrv 97 +Môžem 95 +Hlasovanie 93 +KONIEC 89 +Čauj 89 +Či 88 +Opatrení 88 +ZA EF 87 +Čo 85 +Prekestein 84 +Pol7 M 82 +Preto 80 +Ďakujte 79 +Môsťa 74 +Môjši 74 +Ráčelný 73 +Čes 72 +januára 22 72 +Kto sa zdržal 71 +Čili 71 +Znášť 71 +Čaujte 69 +Hvala što pratite kanal 69 +Časají 68 +Spinelli 68 +Českujem 64 +Čer 63 +Kovým 62 +Čaukujem 62 +Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakujem za pozornosť, Ďakuj 58 +Ďalej 58 +Overejme si 58 +Mátaň 55 +Ďakujem pekne 55 +Kováčný 55 +Časť 1 za 54 +Mňe SAD 52 +proti 51 diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/sl.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/sl.txt new file mode 100644 index 00000000..c08c64f3 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/sl.txt @@ -0,0 +1,363 @@ +Hvala što pratite kanal 988348 +Hvala 461493 +Hvala za pozornost 351855 +Hvala na sviđanju 307238 +Hvala na sviđanje 272988 +Hvala što pratite 37478 +Ďakujem za pozornosť 30823 +Hvala še 29093 +Hvala vam 22922 +Hvala lepa 17965 +Hvala š 10578 +Hvala na 6979 +Hvala za pozornosť 6152 +Hvala vse 5016 +Hvala se 3981 +što pratite kanal 2746 +pratite kanal 2141 +kanal 2139 +na sviđanje 1656 +na sviđanju 1629 +Hvala na to 1618 +Hvala za pozornos 1476 +za pozornost 1313 +Hvala Hvala 1190 +pozornost 1172 +sviđanje 1168 +Hvala za gledanje 1158 +Hvala za 1131 +sviđanju 1114 +Hvala što prat 997 +Hvala je 925 +Hra 866 +Ďakuj 785 +Hvala na vse 775 +Hvala na svojih 759 +Hvala na svoj stvari 702 +Hvala v tem 532 +Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala H 517 +Hvala na svi 502 +Hrv 479 +Pa 462 +Hrani 429 +Hvala da 417 +da 394 +Hvala na pozornost 385 +Hvala še te 360 +Če 354 +Hr 341 +Hvala za pozornosti 329 +Hvala vseh 317 +Hvala na srednje 312 +Hvala te 297 +HDI 294 +Hvala in 284 +Hlasujem 263 +Hvala sem 259 +Hvala šešnje 238 +Hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, hvala, 236 +što pratite 235 +Na 235 +Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hval 234 +Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hval 232 +Hvala pa 231 +Ni 228 +Hvala na sviđanj 222 +Konec 222 +Hrm 222 +Komisja 221 +Hvalda 220 +67 220 +Hvala što 218 +Hvala nič 218 +Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala H 209 +Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala H 208 +Hrpa 202 +Pot 201 +Hvala mi 200 +Hvala vam se 199 +Hvala na svoju 199 +Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala 194 +Zdravljamo 192 +pratite 190 +Hvala le 179 +Hvala še tudi 178 +Hvala na svoj stv 177 +Hvala što ste 177 +Zdravljamo v tem 175 +Hrvatsko 174 +Horda 173 +Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hval 164 +Hvala še nič 158 +Hvala ni 158 +Hvalači 156 +Hvala reči 155 +Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hval 151 +Hvala za pozornoske 150 +Ludi 149 +Kaj 149 +Zaj 149 +Mislim 149 +Lid 148 +in 147 +Anja 147 +Pavel 147 +Da 146 +Hvalače 146 +Hvala lepo 146 +Torej 145 +Hanz 141 +za 137 +Sala 137 +Hvala še vse 135 +UR 135 +Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hval 128 +Hvala na tem 127 +Hvala štine 124 +Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hval 121 +Lepa 120 +Hvala ljudi 119 +Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala H 118 +Hvala za nas 115 +Hvala za minuta 115 +Ali 114 +Hviso 111 +Kovania 111 +Grči 111 +Hvira 111 +Lepen 111 +Koste 111 +Hrce 111 +Kolek 111 +Uvira 111 +Hrano 111 +Kovac 111 +Horema 111 +Prejto 111 +Hvaly 111 +Hvisel 111 +Intervenci 111 +Hrdo 111 +Tvr 111 +Hrmet 111 +vam 110 +Hruba 110 +Hvaliti 110 +Hlede 110 +Krizo 110 +Hrber 110 +Hredal 110 +Uplive 110 +Hlasik 110 +Hrja 110 +Odbora 110 +Rekah 110 +Zdravljte se 109 +Joče 109 +Hrabe 109 +še 108 +Uredbo 108 +Hjel 108 +Hristo 107 +Proti 106 +Hvala še ne 105 +Hvala gospodina 103 +Hrpo 102 +Predlog 100 +Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, Hvala, 95 +Ne 95 +Hvala na sveto 93 +Hrvi 93 +Hrviti 92 +Hvala ljepa 92 +Hvala za te 91 +Hvala in se 90 +Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala 89 +Hvala pre 89 +Hraunman 89 +Hvala Lepa 89 +Odgovoro 89 +Odičja 89 +Hrvoss 89 +Uglasal 89 +Hranih 89 +Hvala sam 88 +Hledajte 88 +Vandekamp 88 +Od drugič 88 +Blaginja 88 +Obdobje 88 +Hrčila 88 +Očasno 88 +Oznako C 87 +Hlasovanie 87 +Hršek 87 +za pozornosť 86 +Horebno 86 +Čila 86 +Hlo plen 85 +Hvala še to 85 +Hrdeve 85 +Hvala vam je 84 +Lina Ebol 83 +Hrmoni 83 +Hrva 83 +pozornosť 82 +Hvala, predsednik 82 +Hvala po 82 +Hvala še prijatelj 80 +Hrvim 80 +lepa 78 +Oktobr 78 +Hvala, mislim 75 +Hvala vprašanje 75 +Hrbæk 74 +Hrani Rez 74 +TKSTOV 74 +Zdravitev 74 +Hvala šeče 74 +Hjerovje 74 +Hrvitsk 74 +je 73 +Hrvicu 73 +Hvalačun 73 +Hvala depa 73 +Obviznice 73 +Hvalačka 73 +Vzgodovino 73 +Hvala leč 73 +Hvala imi 73 +Hrvi Krvi 73 +Hvalačila 73 +Hvala dana 73 +Hvala prednost 73 +Hvalačuna 73 +Hvala tudi 73 +Ravivalstvo 73 +Hvala ni pa 73 +Hločenje 73 +Hvalačena 73 +Swinburne K 73 +Hvala rej 72 +Hvalaček 72 +Hrvodne 72 +Hvala da se 72 +Hvala šli 72 +Hvala zir 72 +Horeizontali 72 +Hrvatske 72 +Odij 72 +Hvala, pa 71 +Hleda se 71 +Hrvatska 71 +Hruzkega 71 +to 70 +Politične 70 +Čini 70 +Houshling 70 +Hvala za besedo 69 +Hvala leo 69 +Klajš 69 +Za 68 +Hvala to, da 68 +Hvala tis 68 +Kretič 68 +Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hval 67 +In 67 +Hlasujemo 67 +Hrspanje 65 +Čloniranje 65 +Čut 65 +Čeho 65 +Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hval 64 +Hvala nekaj 64 +Odporo 64 +Ďakujem 63 +Hvala díti 63 +Hvala na svet 63 +Hvala vam njen 63 +Zdravljenje 63 +Hvala šeba 63 +Hvala predsednik 62 +Hvala na minuto 62 +Hvala je prej 62 +Hvala šultes 62 +Hvala ni zami 62 +Zdravljali 62 +Hvala josti 62 +Hvala rejba 62 +Črnagora 62 +Hrvimam 62 +Uplastmi 62 +Hrvatskene 62 +Opozvalcev 62 +Hrát povem 62 +Zdravljene 62 +Hvala mjeno 62 +Ljubo pri tem 62 +Hocene 62 +Hrčevalce 62 +Corbett 62 +Hvala na pako 62 +Hrvodkih 62 +Hvala komisija 62 +Hvala za inak 62 +Hvala, ne 61 +Článec 61 +Hrvatskih 61 +Hvala za vse 61 +Hvala 3 minuta 61 +Hujbnerjevo 61 +Hvala na rá 60 +Hvala Pils 60 +Tampide 60 +Zdravstveni 60 +Hvala, tak 59 +Čas 58 +Hrčije 57 +Hvali žena 57 +Hrvitič 57 +Hvala za 2016 56 +Hvala še pripravljeni 56 +Hvala še sam 56 +Hvala po dne 56 +Hvala na svej 55 +Aristej 55 +Hvala, sr 55 +Hrvatske Unije 55 +Oznacjavanie 55 +Hvala s priemi 55 +Hrvam ve energie 55 +On 55 +Hvala na svoje 54 +Učinkovitosti 54 +Hvala na vrst 54 +Hvala prijatelj 54 +Hvala predsednika 54 +Hvala še bi 54 +Hvalačevalcu 54 +Hvala za mnogo 54 +Hrvatska Unija 54 +Hrvatske unie 54 +Hvaljujem 54 +Hval 53 +– 90 53 +Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hvala Hval 53 +Hvala na svojih prijatelji 53 +Hrizijski politikami 53 +Hvala za svet 53 +Hvala šičo 53 +Hvala ljima 53 +Hrvatskovič 53 +Hvala le ne 53 +Čána 53 +Hvala vrni 52 +Hvalačevalje 52 +Čelene 52 +Hrčka 52 +Hrspod Florens 51 +Hvala na slob 51 +Hvala predsednice 51 +Hrčevala se 51 +Hvala način 51 +Hrmatikakis 51 diff --git a/dataset_configs/multilingual/yodas2/partials/common_phrases/sv.txt b/dataset_configs/multilingual/yodas2/partials/common_phrases/sv.txt new file mode 100644 index 00000000..96166957 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/common_phrases/sv.txt @@ -0,0 +1,184 @@ +Tack till elever och personer som hjälpte med videon 103409 +nu 56532 +Textning 56034 +Tack till elever och personal vid Säkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssä 41530 +Tack så mycket 23877 +Tack 11914 +Ja 11835 +Vi 3767 +Nej 2753 +Okej 1938 +En 1427 +Tack till elever och personal vid Säkerhetssäkerheten 1183 +Inte 963 +Tack till elever och personal vid Säkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhet 960 +btistudios 914 +Hej 894 +Nej röster 870 +Tack till elever och personal vid Säkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetsäkerhetsäkerhetsäkerhetsäkerhetsä 689 +Om 659 +com www 555 +Men 541 +videon 534 +Det är inte det 532 +till elever och personer som hjälpte med videon 500 +Hej då 482 +med videon 477 +Tack till elever och personal vid Säkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhet 475 +Nu 455 +och personer som hjälpte med videon 448 +Tack till elever och personal vid Säkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhet 440 +Att 433 +Själv 433 +Text 430 +hjälpte med videon 427 +Nej röstar 412 +som hjälpte med videon 398 +Tack till elever och personer som hjälpte mig 386 +elever och personer som hjälpte med videon 367 +Självklart 356 +personer som hjälpte med videon 351 +Varsågod 333 +Nej, röster 330 +Tack till elever och personal vid Säkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhet 318 +Tack till elever och personal vid Säkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhet 316 +Tack till elever och personal vid Säkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetsäkerhetssäkerhetsäkerhetsäkerhetsäkerhetsäkerhetsäkerhetsäkerhetsäkerhetsäkerhetsä 313 +Tack till elever och personal vid Säkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhet 272 +Amen 272 +Tack till elever och personal vid Säkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhet 261 +Vad är det 248 +Tack till elever och personal vid Säkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhet 245 +com 236 +Ett 233 +Fyra 231 +Hur 228 +att 227 +Herr 224 +Till 222 +Textning Stina Hedin www 218 +Hall 217 +Nej, röstar 204 +Svart 204 +Antaget 198 +Det är bra 198 +Tack till elever och personal vid Säkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhet 185 +Välkomna 185 +Så 174 +Och 165 +Antas 156 +Tack till elever och personer som hjälpte oss med videon 152 +Stora 150 +Lags 148 +En moment 148 +Attra 148 +Skandal 148 +Pré 148 +Vi sa 147 +Sats 146 +för 145 +Jag röstar 145 +Kanet 145 +så mycket 144 +Nej, jag röstar 144 +En person 144 +Vi har 143 +Vi är 140 +Stort 138 +Följ oss 132 +mycket 124 +Applåder 123 +till elever och personal vid Säkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssä 122 +det 120 +Tack till elever 118 +Exempel 117 +Hej, hej 115 +Före 113 +com – Textning Stina Hedin www 113 +Alla ett 111 +Gått 111 +Dettajer 111 +SIFTA 111 +Spanier 111 +Jäf 111 +En minutt 110 +Nyanser 110 +Det är inte så bra 103 +Rösta 102 +Nej-röster 102 +Vörr 101 +Två 100 +En annan 100 +Nej, rösta 94 +Tack till elever och personer som hjälpte med 93 +Tack för att du har lyssnat 92 +röster 91 +Delegationen 89 +Själp 89 +Tränsla 89 +Elmån 89 +Låt mig se 89 +Excellenst 89 +Sjåg 89 +Spärgis 88 +Radikalisering 88 +Sjärnor 87 +Exporterna 87 +som 86 +Hur är det 84 +Det stämmer 81 +ÖB 80 +Kompromiss C 80 +Bibliothek 80 +Nej rastar 80 +Vi kan vi 78 +ÖPAPT 77 +Det är inte det här 76 +En lösning 76 +Detta bevis 76 +Hon är nöjd 74 +Texten är 74 +Fyrtysv 74 +Hygienpaket 73 +Låt oss jobba 73 +Det är en bra 73 +Faktiserade vi 73 +Vi har stått 72 +Självna 72 +Tack till elever och personal vid Säkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhet 71 +Alla rätt 71 +Det är så mycket 71 +Vad händer 70 +00 klockan 12 70 +Det är styrt 70 +Sättet 69 +Tack till elever och personal vid Säkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhet 68 +Röstning 68 +Enis 68 +Försättning 67 +IK 67 +här 63 +Det är en roll 62 +Vi är tre 61 +Tack till elever och personal vid Säkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhetssäkerhet 60 +IKT 60 +Det är en annan 59 +Nej restar 59 +En anslutad 58 +Detta är det 58 +Stördjä 58 +Att det finns 58 +Förutningen 57 +En fråga 57 +Välkommen till oss 56 +Det är en lösning 56 +Nej, det är inte det 55 +om 54 +Nejröster 54 +selementet 54 +är 53 +Nej rösta 53 +Det är en fjärd 53 +Föderam 52 +Tack till elever och personer som hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med hjälpte med 51 +Nedlagda 51 +Pifal 51 diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/bg.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/bg.yaml new file mode 100644 index 00000000..d396a1be --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/bg.yaml @@ -0,0 +1,26 @@ +system: | + Описание: + Имате транскрипция, която може да съдържа пунктуация и главни букви, може да не ги съдържа или да съдържа грешна пунктуация. Задачата е да коригирате текста, като възстановите пунктуацията и главните букви. + + Правила: + - Не променяйте, добавяйте или премахвайте думи от текста. Всички промени трябва да бъдат ограничени до пунктуация и главни букви. + - Възстановете правилната пунктуация, като използвате само точки, запетаи, въпросителни знаци, удивителни знаци, точка и запетая, двоеточия и тирета. Всички останали символи (включително емоджита) трябва да бъдат премахнати или заменени с допустими пунктуационни знаци. + - Ако текстът вече съдържа достатъчна пунктуация, оставете го непроменен. + - Коригирайте неправилната или липсваща пунктуация. + - Главните букви трябва да бъдат възстановени за началото на изреченията и собствените имена. + + Примери: + - input: "днес е хубав ден слънцето грее 😊 но е много горещо!!!" + output: "Днес е хубав ден. Слънцето грее, но е много горещо." + + - input: "къде си бил вчера защо не ми се обади 📞" + output: "Къде си бил вчера? Защо не ми се обади?" + + - input: "утре имаме среща в 10 сутринта не закъснявай 😅" + output: "Утре имаме среща в 10 сутринта. Не закъснявай." + + - input: "харесва ми този филм беше много интересен 🍿" + output: "Харесва ми този филм. Беше много интересен." + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/cs.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/cs.yaml new file mode 100644 index 00000000..008be04d --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/cs.yaml @@ -0,0 +1,26 @@ +system: | + Popis: + Máte přepis, který může obsahovat interpunkci a velká písmena, nemusí je obsahovat, nebo obsahuje nesprávnou interpunkci. Úkolem je opravit text obnovením interpunkce a velkých písmen. + + Pravidla: + - Neměňte, nepřidávejte ani neodstraňujte žádná slova z textu. Veškeré úpravy by se měly týkat pouze interpunkce a velkých písmen. + - Obnovte správnou interpunkci pouze s použitím teček, čárek, otazníků, vykřičníků, středníků, dvojteček a pomlček. Všechny ostatní symboly (včetně emoji) musí být odstraněny nebo nahrazeny povolenou interpunkcí. + - Pokud text již obsahuje dostatečnou interpunkci, nechte jej beze změn. + - Opravte nesprávnou nebo chybějící interpunkci. + - Velká písmena používejte na začátku vět a pro vlastní jména. + + Příklady: + - input: "ahoj jak se dnes máš 😊 rád tě vidím!!!" + output: "Ahoj, jak se dnes máš? Rád tě vidím." + + - input: "zítra máme schůzku v 10 hodin ráno nezapomeň 😅" + output: "Zítra máme schůzku v 10 hodin ráno. Nezapomeň." + + - input: "miluji tento film byl tak zajímavý 🎥" + output: "Miluji tento film. Byl tak zajímavý." + + - input: "kde jsi byl včera proč jsi mi nezavolal 📞" + output: "Kde jsi byl včera? Proč jsi mi nezavolal?" + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/da.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/da.yaml new file mode 100644 index 00000000..6008402c --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/da.yaml @@ -0,0 +1,26 @@ +system: | + Beskrivelse: + Du har en transskription, der kan indeholde tegnsætning og store bogstaver, måske ikke indeholder dem, eller indeholder forkert tegnsætning. Opgaven er at rette teksten ved at genoprette tegnsætning og store bogstaver. + + Regler: + - Ændr ikke, tilføj ikke eller fjern nogen ord i teksten. Alle ændringer skal begrænses til tegnsætning og store bogstaver. + - Genopret korrekt tegnsætning ved kun at bruge punktummer, kommaer, spørgsmålstegn, udråbstegn, semikolon, kolon og bindestreger. Alle andre symboler (inklusive emojis) skal fjernes eller erstattes med tilladte tegnsætningstegn. + - Hvis teksten allerede indeholder tilstrækkelig tegnsætning, lad den være uændret. + - Ret forkert eller manglende tegnsætning. + - Brug store bogstaver i begyndelsen af sætninger og for egennavne. + + Eksempler: + - input: "hej hvordan har du det i dag 😊 det er dejligt at se dig!!!" + output: "Hej, hvordan har du det i dag? Det er dejligt at se dig." + + - input: "vi har en aftale i morgen klokken 10 glem det ikke 😅" + output: "Vi har en aftale i morgen klokken 10. Glem det ikke." + + - input: "denne film var fantastisk jeg elskede den 🎥" + output: "Denne film var fantastisk. Jeg elskede den." + + - input: "hvorfor ringede du ikke til mig i går 📞" + output: "Hvorfor ringede du ikke til mig i går?" + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/de.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/de.yaml new file mode 100644 index 00000000..7c81afe2 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/de.yaml @@ -0,0 +1,29 @@ +system: | + Beschreibung: + Sie haben eine Transkription, die möglicherweise Zeichensetzung und Großschreibung enthält, nicht enthält oder fehlerhafte Zeichensetzung aufweist. Die Aufgabe besteht darin, den Text zu korrigieren, indem Zeichensetzung und Großschreibung wiederhergestellt werden. + + Regeln: + - Ändern, hinzufügen oder entfernen Sie keine Wörter im Text. Alle Änderungen müssen sich auf Zeichensetzung und Großschreibung beschränken. + - Stellen Sie die Zeichensetzung nur mit Punkten, Kommas, Fragezeichen, Ausrufezeichen, Strichpunkten, Doppelpunkten und Bindestrichen wieder her. Entfernen oder ersetzen Sie andere Symbole (einschließlich Emojis) durch zulässige Satzzeichen. + - Wenn der Text bereits ausreichend Satzzeichen enthält, lassen Sie ihn unverändert. + - Korrigieren Sie unvollständige oder fehlerhafte Zeichensetzung. + - Die Zeichensetzung muss zum Kontext passen: Verwenden Sie ein Fragezeichen für Fragen und ein Ausrufezeichen für starke Emotionen. + - Schreiben Sie den ersten Buchstaben jedes Satzes groß. + - Schreiben Sie Eigennamen und Abkürzungen groß. + - Wenn der Text mitten in einem Satz beginnt, schreiben Sie das erste Wort nicht groß und fügen Sie keinen Punkt am Ende hinzu. + + Beispiele: + - input: "hallo wie geht es dir heute 😊 ich freue mich dich zu sehen!!!" + output: "Hallo, wie geht es dir heute? Ich freue mich, dich zu sehen." + + - input: "mein telefonnummer ist 1234567890 bitte rufen sie mich an 📞" + output: "Meine Telefonnummer ist 1234567890. Bitte rufen Sie mich an." + + - input: "gestern gingen wir spazieren kauften kaffee und lasen ein buch 📚 es war wunderbar" + output: "Gestern gingen wir spazieren, kauften Kaffee und lasen ein Buch. Es war wunderbar." + + - input: "bist du bereit für das meeting morgen es wird herausfordernd 😅" + output: "Bist du bereit für das Meeting morgen? Es wird herausfordernd." + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/el.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/el.yaml new file mode 100644 index 00000000..875d7ffd --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/el.yaml @@ -0,0 +1,26 @@ +system: | + Περιγραφή: + Έχετε μια απομαγνητοφώνηση που μπορεί να περιέχει σημεία στίξης και κεφαλαία γράμματα, μπορεί να μην τα περιέχει ή να περιέχει λανθασμένα σημεία στίξης. Η αποστολή είναι να διορθώσετε το κείμενο επαναφέροντας τα σημεία στίξης και τα κεφαλαία γράμματα. + + Κανόνες: + - Μην αλλάζετε, προσθέτετε ή αφαιρείτε λέξεις από το κείμενο. Όλες οι αλλαγές πρέπει να περιορίζονται στα σημεία στίξης και στα κεφαλαία γράμματα. + - Επαναφέρετε τα σωστά σημεία στίξης χρησιμοποιώντας μόνο τελείες, κόμματα, ερωτηματικά, θαυμαστικά, άνω τελείες, άνω-κάτω τελείες και παύλες. Όλοι οι άλλοι χαρακτήρες (συμπεριλαμβανομένων των emojis) πρέπει να αφαιρεθούν ή να αντικατασταθούν με επιτρεπτά σημεία στίξης. + - Εάν το κείμενο περιέχει ήδη επαρκή σημεία στίξης, αφήστε το όπως είναι. + - Διορθώστε τα λανθασμένα ή ελλιπή σημεία στίξης. + - Χρησιμοποιήστε κεφαλαία γράμματα στην αρχή κάθε πρότασης και για κύρια ονόματα. + + Παραδείγματα: + - input: "τι όμορφη μέρα σήμερα ο ήλιος λάμπει 😊 αλλά κάνει τόσο κρύο έξω" + output: "Τι όμορφη μέρα σήμερα! Ο ήλιος λάμπει, αλλά κάνει τόσο κρύο έξω." + + - input: "γιατί δεν με πήρες χθες 📞" + output: "Γιατί δεν με πήρες χθες;" + + - input: "αύριο έχουμε συνάντηση φέρε μαζί σου τα έγγραφα" + output: "Αύριο έχουμε συνάντηση. Φέρε μαζί σου τα έγγραφα." + + - input: "πρόσεχε ένα αυτοκίνητο πλησιάζει" + output: "Πρόσεχε! Ένα αυτοκίνητο πλησιάζει." + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/en.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/en.yaml new file mode 100644 index 00000000..9789b1a1 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/en.yaml @@ -0,0 +1,47 @@ +system: | + Description: + You have a transcript that may contain punctuation and capitalization, may not contain them, or may contain incorrect punctuation. The task is to bring the text to the correct form by restoring punctuation and capitalization, ensuring the following rules: + + + Rules: + - Do not change, add, or remove any words in the text. All modifications should be limited to punctuation and capitalization. + - Restore the correct punctuation using only periods, commas, question marks, exclamation marks, semicolons, colons, and dashes. All other symbols (including quotes, parentheses, emojis, etc.) must be removed or replaced with allowed punctuation marks. + - If the text already contains sufficient punctuation (periods, commas, question marks, exclamation marks, semicolons, colons, and dashes), it should remain unchanged. + - If punctuation is incomplete, incorrect, or contains invalid symbols (e.g., ellipses, or other unnecessary symbols), it should be corrected to the proper form using only allowed punctuation. + - Punctuation must match the context: if the sentence is a question, use a question mark at the end. If the sentence expresses excitement or strong emotion, use an exclamation mark. Use periods, commas, semicolons, or colons as needed to separate parts of the sentence. + - All alphanumeric characters (including digits, e.g., 3:30pm) should remain unchanged. + - Capitalize the first letter of each sentence. + - Capitalize proper nouns and abbreviations. + - If the text starts in the middle of a sentence or ends in the middle of a word, do not capitalize the first letter or add a period at the end. + - If punctuation is missing or incorrect, replace invalid symbols with valid punctuation (period, comma, question mark, exclamation mark, semicolon, colon, or dash) without changing the meaning of the text. + + Examples: + - input: "I have 3 pets: a dog, a cat, and a rabbit! ?~_~P??~_~P??~_~P?" + output: "I have 3 pets: a dog, a cat, and a rabbit!" + + - input: "My phone number is 123-456-7890. Call me when you get a chance! ?~_~S~^" + output: "My phone number is 123-456-7890. Call me when you get a chance!" + + - input: "I can't believe this...!!! This is so exciting!!!" + output: "I can't believe this! This is so exciting!" + + - input: "this is a great idea but we need more details"" + output: "This is a great idea, but we need more details." + + - input: "We had a great time ?~@~T everything went smoothly!" + output: "We had a great time ?~@~T everything went smoothly!" + + - input: "hello how are you today :-) I hope you're doing well :)" + output: "Hello, how are you today? I hope you're doing well." + + - input: "the report was almost done, but" + output: "The report was almost done, but" + + - input: "Are you coming to the party: it starts at 8pm" + output: "Are you coming to the party? It starts at 8pm." + + - input: "i need to buy groceries however I don't have much time." + output: "I need to buy groceries; however, I don't have much time." + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/es.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/es.yaml new file mode 100644 index 00000000..67d493c5 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/es.yaml @@ -0,0 +1,28 @@ +system: | + Descripción: + Tienes una transcripción que puede contener puntuación y capitalización, puede no contenerlas, o puede contener puntuación incorrecta. La tarea es corregir el texto restaurando la puntuación y la capitalización. + + Reglas: + - No cambies, añadas ni elimines palabras del texto. Todas las modificaciones deben limitarse a la puntuación y la capitalización. + - Restaura la puntuación usando solo puntos, comas, signos de interrogación, signos de exclamación, puntos y comas, dos puntos y guiones. Elimina o reemplaza cualquier otro símbolo (incluyendo emojis) con puntuación permitida. + - Si el texto ya contiene puntuación suficiente, déjalo sin cambios. + - Corrige la puntuación si es incorrecta o contiene símbolos no válidos. + - La puntuación debe coincidir con el contexto: usa un signo de interrogación para preguntas y un signo de exclamación para expresar emociones. + - Usa mayúsculas en la primera letra de cada oración y para nombres propios o abreviaciones. + - Si el texto empieza en medio de una frase, no pongas mayúsculas al inicio ni punto al final. + + Ejemplos: + - input: "hola como estas hoy 😊 espero que estés bien!!!" + output: "Hola, ¿cómo estás hoy? Espero que estés bien." + + - input: "mi numero de telefono es 1234567890 por favor llámame 📞" + output: "Mi número de teléfono es 1234567890. Por favor, llámame." + + - input: "ayer fuimos al parque compramos helado y jugamos futbol ⚽ fue un gran día" + output: "Ayer fuimos al parque, compramos helado y jugamos fútbol. Fue un gran día." + + - input: "estás listo para el examen mañana creo que será difícil 😅" + output: "¿Estás listo para el examen mañana? Creo que será difícil." + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/et.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/et.yaml new file mode 100644 index 00000000..f4489a14 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/et.yaml @@ -0,0 +1,27 @@ +system: | + Kirjeldus: + Teil on transkriptsioon, mis võib sisaldada kirjavahemärke ja suuri tähti, ei pruugi neid sisaldada või sisaldab valesid kirjavahemärke. Ülesanne on tekst parandada, taastades kirjavahemärgid ja suurtähed. + + Reeglid: + - Ärge muutke, lisage ega eemaldage teksti sõnu. Kõik muudatused peavad piirduma kirjavahemärkide ja suurtähtedega. + - Taastage õiged kirjavahemärgid, kasutades ainult punkte, komasid, küsimärke, hüüumärke, semikooloneid, kooloneid ja kriipse. Kõik muud sümbolid (sh emotikonid) tuleb eemaldada või asendada lubatud kirjavahemärkidega. + - Kui tekst sisaldab juba piisavalt kirjavahemärke, jätke see muutmata. + - Parandage valed või puuduvad kirjavahemärgid. + - Kasutage hüüumärke, kui lause väljendab tugevaid emotsioone või kiiret tegevust. + - Kasutage suurte tähtedega iga lause algust ja nimesid. + + Näited: + - input: "tere kuidas sul täna läheb ma olen nii õnnelik" + output: "Tere, kuidas sul täna läheb? Ma olen nii õnnelik!" + + - input: "me kohtume homme kell 10 ärge hilinege" + output: "Me kohtume homme kell 10. Ärge hilinege!" + + - input: "eile käisime kinos ja see oli nii lõbus" + output: "Eile käisime kinos ja see oli nii lõbus!" + + - input: "vaata ette auto tuleb" + output: "Vaata ette! Auto tuleb!" + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/fi.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/fi.yaml new file mode 100644 index 00000000..54e5099d --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/fi.yaml @@ -0,0 +1,27 @@ +system: | + Kuvaus: + Sinulla on transkriptio, joka voi sisältää välimerkkejä ja isoja kirjaimia, ei välttämättä sisällä niitä tai sisältää virheellisiä välimerkkejä. Tehtävä on korjata teksti palauttamalla välimerkit ja isot kirjaimet. + + Säännöt: + - Älä muuta, lisää tai poista sanoja tekstistä. Kaikki muutokset tulee rajoittaa välimerkkeihin ja isoihin kirjaimiin. + - Palauta oikeat välimerkit käyttämällä vain pisteitä, pilkkuja, kysymysmerkkejä, huutomerkkejä, puolipisteitä, kaksoispisteitä ja tavuviivoja. Kaikki muut symbolit (mukaan lukien emojit) on poistettava tai korvattava sallitulla välimerkillä. + - Jos tekstissä on jo riittävästi välimerkkejä, jätä se muuttamatta. + - Korjaa virheelliset tai puuttuvat välimerkit. + - Käytä huutomerkkejä ilmaisemaan vahvoja tunteita tai kiireellisiä tilanteita. + - Käytä isoja kirjaimia lauseiden alussa ja erisnimissä. + + Esimerkit: + - input: "mikä kaunis päivä tänään on mutta ulkona on niin kylmä" + output: "Mikä kaunis päivä tänään on! Mutta ulkona on niin kylmä." + + - input: "tule huomenna aikaisin meidän täytyy lähteä kello 7" + output: "Tule huomenna aikaisin! Meidän täytyy lähteä kello 7." + + - input: "eilen meillä oli paljon hauskaa ystävien kanssa" + output: "Eilen meillä oli paljon hauskaa ystävien kanssa." + + - input: "varo auto tulee" + output: "Varo! Auto tulee!" + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/fr.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/fr.yaml new file mode 100644 index 00000000..44a9c409 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/fr.yaml @@ -0,0 +1,43 @@ +system: | + Description: + Vous avez une transcription qui peut contenir une ponctuation et une capitalisation, ne pas en contenir, ou contenir une ponctuation incorrecte. La tâche consiste à remettre le texte en forme correcte en restaurant la ponctuation et la capitalisation. + + Règles: + - Ne changez pas, n'ajoutez pas et ne supprimez aucun mot du texte. Toutes les modifications doivent se limiter à la ponctuation et à la capitalisation. + - Restaurez la ponctuation correcte en utilisant uniquement des points, des virgules, des points d'interrogation, des points d'exclamation, des points-virgules, des deux-points et des tirets. Tous les autres symboles (y compris les guillemets, parenthèses, émojis, etc.) doivent être supprimés ou remplacés par des signes de ponctuation autorisés. + - Si le texte contient déjà une ponctuation suffisante (points, virgules, points d'interrogation, points d'exclamation, points-virgules, deux-points et tirets), il doit rester inchangé. + - Si la ponctuation est incomplète, incorrecte ou contient des symboles invalides (par exemple, des ellipses ou d'autres symboles inutiles), elle doit être corrigée sous la forme correcte en utilisant uniquement les signes de ponctuation autorisés. + - La ponctuation doit correspondre au contexte: si la phrase est une question, utilisez un point d'interrogation à la fin. Si la phrase exprime de l'excitation ou une émotion forte, utilisez un point d'exclamation. Utilisez des points, des virgules, des points-virgules ou des deux-points au besoin pour séparer les parties de la phrase. + - Tous les caractères alphanumériques (y compris les chiffres, par ex. 3:30pm) doivent rester inchangés. + - Mettez en majuscule la première lettre de chaque phrase. + - Mettez en majuscule les noms propres et les abréviations. + - Si le texte commence au milieu d'une phrase ou se termine au milieu d'un mot, ne mettez pas la première lettre en majuscule et n'ajoutez pas de point à la fin. + - Si la ponctuation est absente ou incorrecte, remplacez les symboles invalides par une ponctuation valide (point, virgule, point d'interrogation, point d'exclamation, point-virgule, deux-points ou tiret) sans changer le sens du texte. + + Exemples: + - input: "la capitale de la france est paris 🗼 elle est connue pour la tour eiffel!!!" + output: "La capitale de la France est Paris. Elle est connue pour la tour Eiffel!" + + - input: "bonjour comment allez vous aujourd'hui 😊 je suis content de vous voir" + output: "Bonjour, comment allez-vous aujourd'hui? Je suis content de vous voir." + + - input: "nous avons acheté 5 pommes, 3 oranges, et 2 bananes...! 🍎🍌" + output: "Nous avons acheté 5 pommes, 3 oranges et 2 bananes." + + - input: "le soleil brille aujourd'hui mais il fait un peu froid dehors ❄️" + output: "Le soleil brille aujourd'hui, mais il fait un peu froid dehors." + + - input: "je dois appeler mon ami paul 😅 mais je n'ai pas son numéro" + output: "Je dois appeler mon ami Paul, mais je n'ai pas son numéro." + + - input: "il est 3:30pm maintenant, on se retrouve a 4pm?" + output: "Il est 3:30pm maintenant. On se retrouve à 4pm?" + + - input: "je ne comprends pas ce que tu veux dire...!! 🤔 peux tu expliquer encore?" + output: "Je ne comprends pas ce que tu veux dire! Peux-tu expliquer encore?" + + - input: "la date d'aujourd'hui est le 1er janvier 2023 🎉 bonne année à tous!" + output: "La date d'aujourd'hui est le 1er janvier 2023. Bonne année à tous!" + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/hr.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/hr.yaml new file mode 100644 index 00000000..e81f185b --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/hr.yaml @@ -0,0 +1,26 @@ +system: | + Opis: + Imate transkripciju koja može sadržavati interpunkciju i velika slova, možda ih ne sadrži ili sadrži pogrešnu interpunkciju. Zadatak je ispraviti tekst vraćanjem ispravne interpunkcije i velikih slova. + + Pravila: + - Nemojte mijenjati, dodavati ili uklanjati riječi iz teksta. Sve izmjene trebaju biti ograničene na interpunkciju i velika slova. + - Vratite ispravnu interpunkciju koristeći samo točke, zareze, upitnike, uskličnike, točke sa zarezom, dvotočke i crtice. Svi ostali simboli (uključujući emojije) moraju biti uklonjeni ili zamijenjeni dopuštenim interpunkcijskim znakovima. + - Ako tekst već ima dovoljno interpunkcije, ostavite ga nepromijenjenim. + - Ispravite pogrešnu ili nedostajuću interpunkciju. + - Koristite velika slova na početku svake rečenice i za vlastita imena. + + Primjeri: + - input: "kakav divan dan danas sunce sja 😊 ali vani je tako hladno" + output: "Kakav divan dan danas! Sunce sja, ali vani je tako hladno." + + - input: "zašto mi nisi jučer nazvao 📞" + output: "Zašto mi nisi jučer nazvao?" + + - input: "sutra imamo sastanak ne zaboravi dokumente" + output: "Sutra imamo sastanak. Ne zaboravi dokumente." + + - input: "pazi auto dolazi" + output: "Pazi! Auto dolazi." + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/hu.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/hu.yaml new file mode 100644 index 00000000..ce59b5b2 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/hu.yaml @@ -0,0 +1,26 @@ +system: | + Leírás: + Van egy átirat, amely tartalmazhat írásjeleket és nagybetűket, lehet, hogy nem tartalmazza őket, vagy hibás írásjeleket tartalmaz. A feladat az, hogy helyreállítsa a helyesírást és az írásjeleket. + + Szabályok: + - Ne változtasson, ne adjon hozzá és ne töröljön szavakat a szövegben. Az összes változtatásnak az írásjelekre és a nagybetűkre kell korlátozódnia. + - Állítsa vissza a helyes írásjeleket, használva csak pontot, vesszőt, kérdőjelet, felkiáltójelet, pontosvesszőt, kettőspontot és kötőjelet. Az összes többi szimbólumot (beleértve az emojikat) törölni kell, vagy helyettesíteni engedélyezett írásjelekkel. + - Ha a szöveg már elegendő írásjeleket tartalmaz, hagyja változatlanul. + - Javítsa a hibás vagy hiányzó írásjeleket. + - Használjon nagybetűt minden mondat elején és tulajdonneveknél. + + Példák: + - input: "milyen szép nap van ma a nap ragyog de kint olyan hideg van" + output: "Milyen szép nap van ma! A nap ragyog, de kint olyan hideg van." + + - input: "miért nem hívtál tegnap 📞" + output: "Miért nem hívtál tegnap?" + + - input: "tegnap elmentünk a parkba és nagyon jól éreztük magunkat" + output: "Tegnap elmentünk a parkba, és nagyon jól éreztük magunkat." + + - input: "vigyázz jön egy autó" + output: "Vigyázz! Jön egy autó!" + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/it.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/it.yaml new file mode 100644 index 00000000..8a4592ca --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/it.yaml @@ -0,0 +1,27 @@ +system: | + Descrizione: + Hai una trascrizione che potrebbe contenere punteggiatura e lettere maiuscole, potrebbe non contenerle o potrebbe avere una punteggiatura errata. Il compito è correggere il testo ripristinando la punteggiatura e le lettere maiuscole. + + Regole: + - Non modificare, aggiungere o rimuovere parole dal testo. Tutte le modifiche devono essere limitate alla punteggiatura e alle maiuscole. + - Ripristina la punteggiatura corretta utilizzando solo punti, virgole, punti interrogativi, punti esclamativi, punti e virgola, due punti e trattini. Tutti gli altri simboli (inclusi emoji) devono essere rimossi o sostituiti con segni di punteggiatura consentiti. + - Se il testo contiene già una punteggiatura sufficiente, lascialo invariato. + - Correggi la punteggiatura errata o mancante. + - Usa punti esclamativi per esprimere forti emozioni o urgenza. + - Usa lettere maiuscole all'inizio di ogni frase e per nomi propri. + + Esempi: + - input: "che bel giorno oggi il sole splende 😊 ma fuori fa così freddo" + output: "Che bel giorno oggi! Il sole splende, ma fuori fa così freddo." + + - input: "arriva presto domani dobbiamo partire alle 7 😅" + output: "Arriva presto domani! Dobbiamo partire alle 7." + + - input: "ieri siamo andati al parco e ci siamo divertiti molto" + output: "Ieri siamo andati al parco e ci siamo divertiti molto." + + - input: "attento c'è una macchina" + output: "Attento! C'è una macchina!" + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/lt.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/lt.yaml new file mode 100644 index 00000000..6e0eb355 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/lt.yaml @@ -0,0 +1,27 @@ +system: | + Aprašymas: + Jūs turite transkripciją, kurioje gali būti skyrybos ženklų ir didžiųjų raidžių, jų gali nebūti arba jie gali būti neteisingi. Užduotis yra ištaisyti tekstą, atkuriant skyrybos ženklus ir didžiąsias raides. + + Taisyklės: + - Nekeiskite, nepridėkite ir neištrinkite žodžių iš teksto. Visos pataisos turi būti apribotos skyrybos ženklais ir didžiosiomis raidėmis. + - Atkurkite tinkamus skyrybos ženklus, naudodami tik taškus, kablelius, klaustukus, šauktukus, kabliataškius, dvitaškius ir brūkšnius. Visi kiti simboliai (įskaitant jaustukus) turi būti pašalinti arba pakeisti leidžiamais skyrybos ženklais. + - Jei tekstas jau turi pakankamai skyrybos ženklų, palikite jį nepakeistą. + - Ištaisykite neteisingus arba trūkstamus skyrybos ženklus. + - Naudokite šauktukus, kad išreikštumėte stiprias emocijas ar skubumą. + - Naudokite didžiąsias raides kiekvieno sakinio pradžioje ir tikriniams vardams. + + Pavyzdžiai: + - input: "kokia nuostabi diena šiandien saulė šviečia 😊 bet lauke taip šalta" + output: "Kokia nuostabi diena šiandien! Saulė šviečia, bet lauke taip šalta." + + - input: "rytoj turime išvykti anksti nepramiegok 😅" + output: "Rytoj turime išvykti anksti! Nepramiegok." + + - input: "vakar ėjome į parką ir buvo labai smagu" + output: "Vakar ėjome į parką ir buvo labai smagu." + + - input: "žiūrėk automobilis atvažiuoja" + output: "Žiūrėk! Automobilis atvažiuoja!" + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/lv.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/lv.yaml new file mode 100644 index 00000000..1c0516cd --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/lv.yaml @@ -0,0 +1,27 @@ +system: | + Apraksts: + Jums ir transkripcija, kurā var būt pieturzīmes un lielie burti, kurā var nebūt vai kurā var būt nepareizas pieturzīmes. Uzdevums ir labot tekstu, atjaunojot pieturzīmes un lielos burtus. + + Noteikumi: + - Nemainiet, nepievienojiet un neizdzēsiet nevienu vārdu tekstā. Visas izmaiņas jāierobežo ar pieturzīmēm un lielajiem burtiem. + - Atjaunojiet pareizās pieturzīmes, izmantojot tikai punktus, komatus, jautājumzīmes, izsaukuma zīmes, semikolus, kolus un domuzīmes. Visi citi simboli (ieskaitot emocijzīmes) ir jāizdzēš vai jānomaina ar pieļaujamām pieturzīmēm. + - Ja tekstā jau ir pietiekami daudz pieturzīmju, atstājiet to nemainītu. + - Izlabojiet nepareizas vai trūkstošas pieturzīmes. + - Lietojiet izsaukuma zīmes, lai izteiktu spēcīgas emocijas vai steidzamību. + - Izmantojiet lielos burtus katras teikuma sākumā un īpašvārdiem. + + Piemēri: + - input: "cik jauka diena šodien saule spīd 😊 bet ārā ir tik auksti" + output: "Cik jauka diena šodien! Saule spīd, bet ārā ir tik auksti." + + - input: "rīt mēs ceļosim agri mums jāiziet 7 no rīta 😅" + output: "Rīt mēs ceļosim agri! Mums jāiziet 7 no rīta." + + - input: "vakar mēs devāmies uz parku un pavadījām brīnišķīgu dienu" + output: "Vakar mēs devāmies uz parku un pavadījām brīnišķīgu dienu." + + - input: "uzmanies tuvojas mašīna" + output: "Uzmanies! Tuvojas mašīna!" + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/mt.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/mt.yaml new file mode 100644 index 00000000..f7d95574 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/mt.yaml @@ -0,0 +1,26 @@ +system: | + Deskrizzjoni: + Għandek traskrizzjoni li tista' tinkludi punteġġjatura u ittri kapitali, tista' ma tinkludihomx, jew għandha punteġġjatura żbaljata. Il-kompitu huwa li tirrestawra l-punteġġjatura u l-ittri kapitali fil-forma korretta. + + Regoli: + - Tibdilx, iżżidx jew tneħħix kliem mit-test. Il-bidliet kollha għandhom ikunu limitati għall-punteġġjatura u l-ittri kapitali. + - Irrestawra punteġġjatura korretta billi tuża biss punti, virgoli, punti mistoqsija, sinjali ta’ eżeklamazzjoni, punti u virgoli, żewġ punti u ċertu simboli permessi. Emojis għandhom jitneħħew jew jinbidlu b’punteġġjatura valida. + - Jekk it-test diġà għandu biżżejjed punteġġjatura, ħallih kif inhu. + - Ikkoreġi punteġġjatura ħażina jew nieqsa. + - Uża ittri kapitali fil-bidu ta' kull sentenza u għal ismijiet proprji. + + Eżempji: + - input: "kemm hu sabiħ il-jum illum ix-xemx qed tiddi 😊 imma barra kiesaħ ħafna" + output: "Kemm hu sabiħ il-jum illum! Ix-xemx qed tiddi, imma barra kiesaħ ħafna." + + - input: "għaliex ma ċempiltx ilbieraħ 📞" + output: "Għaliex ma ċempiltx ilbieraħ?" + + - input: "ilbieraħ morna l-park u kellna ħafna gost" + output: "Ilbieraħ morna l-park, u kellna ħafna gost." + + - input: "oqgħod attent hemm karozza ġejja" + output: "Oqgħod attent! Hemm karozza ġejja." + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/nl.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/nl.yaml new file mode 100644 index 00000000..22069c31 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/nl.yaml @@ -0,0 +1,27 @@ +system: | + Beschrijving: + Je hebt een transcriptie die interpunctie en hoofdletters kan bevatten, niet kan bevatten, of verkeerde interpunctie kan bevatten. De taak is om de tekst te corrigeren door de interpunctie en hoofdletters te herstellen. + + Regels: + - Verander, voeg niets toe of verwijder geen woorden uit de tekst. Alle wijzigingen moeten beperkt blijven tot interpunctie en hoofdletters. + - Herstel de juiste interpunctie met alleen punten, komma's, vraagtekens, uitroeptekens, puntkomma's, dubbele punten en streepjes. Alle andere symbolen (inclusief emoji's) moeten worden verwijderd of vervangen door toegestane interpunctietekens. + - Als de tekst al voldoende interpunctie bevat, laat deze dan ongewijzigd. + - Corrigeer foutieve of ontbrekende interpunctie. + - Gebruik uitroeptekens om sterke emoties of urgentie te uiten. + - Gebruik hoofdletters aan het begin van elke zin en voor eigennamen. + + Voorbeelden: + - input: "wat een mooie dag vandaag de zon schijnt 😊 maar het is zo koud buiten" + output: "Wat een mooie dag vandaag! De zon schijnt, maar het is zo koud buiten." + + - input: "kom morgen vroeg we moeten om 7 uur vertrekken 😅" + output: "Kom morgen vroeg! We moeten om 7 uur vertrekken." + + - input: "gisteren gingen we naar het park en hadden veel plezier" + output: "Gisteren gingen we naar het park en hadden veel plezier." + + - input: "pas op er komt een auto" + output: "Pas op! Er komt een auto!" + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/pl.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/pl.yaml new file mode 100644 index 00000000..741acc73 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/pl.yaml @@ -0,0 +1,27 @@ +system: | + Opis: + Masz transkrypcję, która może zawierać interpunkcję i wielkie litery, może ich nie zawierać lub zawierać nieprawidłową interpunkcję. Zadanie polega na poprawieniu tekstu poprzez przywrócenie interpunkcji i wielkich liter. + + Zasady: + - Nie zmieniaj, nie dodawaj ani nie usuwaj żadnych słów w tekście. Wszystkie zmiany powinny ograniczać się do interpunkcji i wielkich liter. + - Przywróć poprawną interpunkcję, używając tylko kropek, przecinków, znaków zapytania, wykrzykników, średników, dwukropków i myślników. Wszystkie inne symbole (w tym emotikony) muszą zostać usunięte lub zastąpione dozwolonymi znakami interpunkcyjnymi. + - Jeśli tekst już zawiera wystarczającą interpunkcję, pozostaw go bez zmian. + - Popraw błędną lub brakującą interpunkcję. + - Używaj wykrzykników, aby wyrazić silne emocje lub pilność. + - Używaj wielkich liter na początku każdego zdania i dla nazw własnych. + + Przykłady: + - input: "jaki piękny dzień dzisiaj słońce świeci 😊 ale na dworze jest tak zimno" + output: "Jaki piękny dzień dzisiaj! Słońce świeci, ale na dworze jest tak zimno." + + - input: "obudzimy się wcześnie jutro musimy wyjść o 7 😅" + output: "Obudzimy się wcześnie jutro! Musimy wyjść o 7." + + - input: "wczoraj byliśmy w parku było tak fajnie" + output: "Wczoraj byliśmy w parku. Było tak fajnie." + + - input: "uważaj samochód nadjeżdża" + output: "Uważaj! Samochód nadjeżdża!" + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/pt.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/pt.yaml new file mode 100644 index 00000000..17f0b80f --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/pt.yaml @@ -0,0 +1,27 @@ +system: | + Descrição: + Você tem uma transcrição que pode conter pontuação e letras maiúsculas, pode não conter ou pode conter pontuação incorreta. A tarefa é corrigir o texto restaurando a pontuação e as letras maiúsculas. + + Regras: + - Não altere, adicione ou remova palavras do texto. Todas as alterações devem se limitar à pontuação e letras maiúsculas. + - Restaure a pontuação correta usando apenas pontos, vírgulas, pontos de interrogação, pontos de exclamação, pontos e vírgulas, dois-pontos e traços. Todos os outros símbolos (incluindo emojis) devem ser removidos ou substituídos por pontuação permitida. + - Se o texto já contiver pontuação suficiente, deixe-o inalterado. + - Corrija pontuações incorretas ou ausentes. + - Use pontos de exclamação para expressar fortes emoções ou urgência. + - Use letras maiúsculas no início de cada frase e para nomes próprios. + + Exemplos: + - input: "que dia lindo hoje o sol está brilhando 😊 mas está tão frio lá fora" + output: "Que dia lindo hoje! O sol está brilhando, mas está tão frio lá fora." + + - input: "amanhã temos que sair cedo não se atrase 😅" + output: "Amanhã temos que sair cedo! Não se atrase." + + - input: "ontem fomos ao parque foi muito divertido" + output: "Ontem fomos ao parque. Foi muito divertido." + + - input: "cuidado um carro está vindo" + output: "Cuidado! Um carro está vindo!" + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/ro.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/ro.yaml new file mode 100644 index 00000000..9f97300d --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/ro.yaml @@ -0,0 +1,26 @@ +system: | + Descriere: + Aveți o transcriere care poate conține punctuație și majuscule, poate să nu le conțină sau poate avea punctuație greșită. Sarcina este să corectați textul prin restaurarea punctuației și majusculelor. + + Reguli: + - Nu modificați, adăugați sau eliminați cuvinte din text. Toate modificările trebuie să fie limitate la punctuație și majuscule. + - Restaurați punctuația corectă folosind doar puncte, virgule, semne de întrebare, semne de exclamare, puncte și virgule, două puncte și cratime. Toate celelalte simboluri (inclusiv emoji) trebuie eliminate sau înlocuite cu semne de punctuație permise. + - Dacă textul are deja suficientă punctuație, lăsați-l neschimbat. + - Corectați punctuația incorectă sau lipsă. + - Folosiți majuscule la începutul fiecărei fraze și pentru numele proprii. + + Exemple: + - input: "ce zi frumoasă astăzi soarele strălucește 😊 dar este atât de frig afară" + output: "Ce zi frumoasă astăzi! Soarele strălucește, dar este atât de frig afară." + + - input: "unde ai fost ieri de ce nu m-ai sunat 📞" + output: "Unde ai fost ieri? De ce nu m-ai sunat?" + + - input: "ieri am fost la cumpărături am cumpărat mere pere și portocale" + output: "Ieri am fost la cumpărături. Am cumpărat mere, pere și portocale." + + - input: "ai grijă vine o mașină" + output: "Ai grijă! Vine o mașină." + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/ru.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/ru.yaml new file mode 100644 index 00000000..288948e7 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/ru.yaml @@ -0,0 +1,61 @@ +system: | + Описание: + У вас есть текст, который может содержать пунктуацию и капитализацию, может не содержать их или содержать некорректную пунктуацию. Задача — привести текст к правильной форме, восстановив пунктуацию и капитализацию, соблюдая следующие правила: + + Правила: + - Не изменять, не добавлять и не удалять слова в тексте. Все изменения должны касаться только пунктуации и капитализации. + - Восстанавливать правильную пунктуацию, используя только точки, запятые, вопросы, восклицательные знаки, точки с запятой, двоеточия и тире. Все остальные символы (включая кавычки, скобки, смайлики и т.д.) должны быть удалены или заменены разрешенными знаками пунктуации. + - Если в тексте уже есть достаточная пунктуация (точки, запятые, вопросы, восклицательные знаки, точки с запятой, двоеточия и тире), она должна оставаться без изменений. + - Если пунктуация неполная, некорректная или содержит недопустимые символы (например, многоточие или другие лишние символы), они должны быть заменены на правильную пунктуацию с использованием только разрешенных знаков. + - Пунктуация должна соответствовать контексту: если предложение является вопросом, в конце должен быть вопросительный знак. Если предложение выражает волнение или сильные эмоции, используйте восклицательный знак. Точки, запятые, точки с запятой или двоеточия должны использоваться для разделения частей предложения. + - Все алфавитно-цифровые символы (включая цифры, например, 15:30) должны оставаться без изменений. + - Заглавную букву следует ставить в начале каждого предложения. + - Заглавными буквами следует писать имена собственные и аббревиатуры. + - Если текст начинается в середине предложения или заканчивается на середине слова, не нужно ставить заглавную букву в начале и не нужно добавлять точку в конце. + - Если пунктуация отсутствует или неправильная, замените недопустимые символы на правильные знаки пунктуации (точка, запятая, вопросительный знак, восклицательный знак, точка с запятой, двоеточие или тире) без изменения смысла текста. + + Примеры: + - input: "я так и не понял, что произошло" + output: "Я так и не понял, что произошло." + + - input: "Знаешь, я думал что мы пойдем в кино, а оказывается отменили сеанс, обидно!" + output: "Знаешь, я думал, что мы пойдем в кино, а оказывается, отменили сеанс. Обидно!" + + - input: "Как ты? давно не виделись! ну как дела?" + output: "Как ты? Давно не виделись! Ну как дела?" + + - input: "Этот вопрос требует внимания а если честно он довольно сложный" + output: "Этот вопрос требует внимания, а если честно, он довольно сложный." + + - input: "Сегодня вечером мы будем обсуждать проект- нам нужно завершить работу к 20:00" + output: "Сегодня вечером мы будем обсуждать проект — нам нужно завершить работу к 20:00." + + - input: "игорь не пришел на встречу... может быть он опоздает?" + output: "Игорь не пришел на встречу. Может быть, он опоздает?" + + - input: "ты видела этот фильм? просто невероятно, как такое вообще снимают" + output: "Ты видела этот фильм? Просто невероятно, как такое вообще снимают!" + + - input: "Мы почти пришли домой но мне нужно заехать за продуктами" + output: "Мы почти пришли домой, но мне нужно заехать за продуктами." + + - input: "Привет, что ты думаешь по поводу нового закона? он реально важен для экономики." + output: "Привет, что ты думаешь по поводу нового закона? Он реально важен для экономики." + + - input: "Она сказала ну не знаю посмотрим" + output: "Она сказала: ну, не знаю, посмотрим." + + - input: "Ты мне не ответил на прошлый вопрос :(" + output: "Ты мне не ответил на прошлый вопрос." + + - input: "Зачем ты так? Это не твоя вина не переживай:)" + output: "Зачем ты так? Это не твоя вина, не переживай!" + + - input: "А вот и новость! Ура нам удалось завершить проект! :D" + output: "А вот и новость! Ура, нам удалось завершить проект!" + + - input: "Я был в шоке от увиденного не мог поверить :O" + output: "Я был в шоке от увиденного, не мог поверить!" + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/sk.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/sk.yaml new file mode 100644 index 00000000..ef078993 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/sk.yaml @@ -0,0 +1,26 @@ +system: | + Popis: + Máte prepis, ktorý môže obsahovať interpunkciu a veľké písmená, nemusí ich obsahovať, alebo obsahuje nesprávnu interpunkciu. Úlohou je opraviť text obnovením interpunkcie a veľkých písmen. + + Pravidlá: + - Nemeňte, nepridávajte ani neodstraňujte žiadne slová z textu. Všetky úpravy by sa mali týkať iba interpunkcie a veľkých písmen. + - Obnovte správnu interpunkciu pomocou bodiek, čiarok, otáznikov, výkričníkov, bodkočiarok, dvojbodiek a pomlčiek. Všetky ostatné symboly (vrátane emoji) musia byť odstránené alebo nahradené povolenou interpunkciou. + - Ak text už obsahuje dostatočnú interpunkciu, nechajte ho nezmenený. + - Opravte nesprávnu alebo chýbajúcu interpunkciu. + - Používajte veľké písmená na začiatku viet a pre vlastné mená. + + Príklady: + - input: "aké krásne počasie dnes slnko svieti 😊 ale vonku je zima" + output: "Aké krásne počasie dnes! Slnko svieti, ale vonku je zima." + + - input: "prečo si mi nezavolal včera 📞" + output: "Prečo si mi nezavolal včera?" + + - input: "zajtra máme stretnutie nezabudni si dokumenty" + output: "Zajtra máme stretnutie. Nezabudni si dokumenty." + + - input: "pozor auto prichádza" + output: "Pozor! Auto prichádza." + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/sl.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/sl.yaml new file mode 100644 index 00000000..93117503 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/sl.yaml @@ -0,0 +1,26 @@ +system: | + Opis: + Imate transkripcijo, ki lahko vsebuje ločila in velike črke, jih morda ne vsebuje, ali pa vsebuje napačna ločila. Naloga je popraviti besedilo z obnovo pravilnih ločil in velikih črk. + + Pravila: + - Ne spreminjajte, dodajajte ali odstranjujte besed v besedilu. Vse spremembe naj se omejijo na ločila in velike črke. + - Obnovite pravilna ločila z uporabo le pik, vejic, vprašajev, klicajev, podpičij, dvopičij in pomišljajev. Vsi drugi simboli (vključno z emojiji) naj se odstranijo ali zamenjajo z dovoljenimi ločili. + - Če besedilo že vsebuje dovolj ločil, naj ostane nespremenjeno. + - Popravite napačna ali manjkajoča ločila. + - Uporabite velike črke na začetku stavkov in za lastna imena. + + Primeri: + - input: "kakšen čudovit dan danes sonce sije 😊 ampak zunaj je tako mrzlo" + output: "Kakšen čudovit dan danes! Sonce sije, ampak zunaj je tako mrzlo." + + - input: "zakaj me nisi poklical včeraj 📞" + output: "Zakaj me nisi poklical včeraj?" + + - input: "jutri imamo sestanek ne pozabi dokumentov" + output: "Jutri imamo sestanek. Ne pozabi dokumentov." + + - input: "pazi prihaja avto" + output: "Pazi! Prihaja avto." + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/sv.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/sv.yaml new file mode 100644 index 00000000..f309a0e1 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/sv.yaml @@ -0,0 +1,26 @@ +system: | + Beskrivning: + Du har en transkription som kan innehålla interpunktion och stora bokstäver, kanske inte innehåller dem eller innehåller felaktig interpunktion. Uppgiften är att rätta texten genom att återställa interpunktion och stora bokstäver. + + Regler: + - Ändra inte, lägg inte till eller ta bort några ord i texten. Alla ändringar ska begränsas till interpunktion och stora bokstäver. + - Återställ korrekt interpunktion med bara punkter, kommatecken, frågetecken, utropstecken, semikolon, kolon och bindestreck. Alla andra symboler (inklusive emojis) måste tas bort eller ersättas med tillåtna interpunktionstecken. + - Om texten redan innehåller tillräcklig interpunktion, lämna den oförändrad. + - Rätta felaktig eller saknad interpunktion. + - Använd stora bokstäver i början av varje mening och för egennamn. + + Exempel: + - input: "vilken vacker dag solen skiner men det är så kallt ute" + output: "Vilken vacker dag! Solen skiner, men det är så kallt ute." + + - input: "varför ringde du inte igår 📞" + output: "Varför ringde du inte igår?" + + - input: "vi gick till parken igår och hade så kul" + output: "Vi gick till parken igår och hade så kul." + + - input: "se upp bilen kommer" + output: "Se upp! Bilen kommer!" + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/uk.yaml b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/uk.yaml new file mode 100644 index 00000000..88d7744b --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/pr_recovery_prompts/uk.yaml @@ -0,0 +1,26 @@ +system: | + Опис: + Ви маєте транскрипцію, яка може містити знаки пунктуації та великі літери, може не містити їх або містити неправильні знаки пунктуації. Завдання полягає у виправленні тексту шляхом відновлення пунктуації та великих літер. + + Правила: + - Не змінюйте, не додавайте і не видаляйте слова з тексту. Усі зміни повинні обмежуватися пунктуацією та великими літерами. + - Відновіть правильну пунктуацію, використовуючи лише крапки, коми, знаки питання, знаки оклику, крапки з комою, двокрапки та тире. Усі інші символи (включно з емодзі) необхідно видалити або замінити дозволеними знаками пунктуації. + - Якщо текст уже містить достатньо пунктуації, залиште його без змін. + - Виправте неправильну або відсутню пунктуацію. + - Використовуйте великі літери на початку кожного речення та для власних назв. + + Приклади: + - input: "який прекрасний день сьогодні сонце світить 😊 але надворі так холодно" + output: "Який прекрасний день сьогодні! Сонце світить, але надворі так холодно." + + - input: "чому ти не подзвонив вчора 📞" + output: "Чому ти не подзвонив вчора?" + + - input: "завтра у нас зустріч не забудь взяти документи" + output: "Завтра у нас зустріч. Не забудь взяти документи." + + - input: "будь обережним наближається автомобіль" + output: "Будь обережним! Наближається автомобіль." + +user: | + Input transcript: {text} diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/bg.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/bg.yaml new file mode 100644 index 00000000..467930cc --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/bg.yaml @@ -0,0 +1,30 @@ +- {'pattern': 'ă', 'repl': 'a'} +- {'pattern': 'ğ', 'repl': 'g'} +- {'pattern': 'ş', 'repl': 's'} +- {'pattern': 'ó', 'repl': 'o'} +- {'pattern': 'é', 'repl': 'e'} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "—", "repl": ' '} +- {"pattern": "–", "repl": ' '} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': ' '} + +- {"pattern": "[^ €₽₴$£%?!',.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЬЮЯабвгдежзийклмнопрстуфхцчшщъьюя]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} + diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/common.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/common.yaml new file mode 100644 index 00000000..950d932f --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/common.yaml @@ -0,0 +1,31 @@ +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": "—", "repl": "-"} +- {"pattern": "–", "repl": "-"} +- {"pattern": "-", "repl": "-"} +- {"pattern": "_", "repl": " "} +- {"pattern": "——", "repl": "-"} +- {"pattern": "Ё", "repl": "Е"} +- {"pattern": "ё", "repl": "е"} + +- {"pattern": "♫", "repl": " "} +- {"pattern": "♪", "repl": " "} +- {"pattern": "♬", "repl": " "} +- {"pattern": "♩", "repl": " "} +- {"pattern": "♭", "repl": " "} +- {"pattern": '\|', "repl": " "} # : -> : +- {"pattern": ";", "repl": ","} + +- {"pattern": '\[[^\]]*\]', "repl": ""} # delete content inside [] +- {"pattern": ' ?\([^\)]+\)', "repl": ""} # delete content inside () +- {"pattern": ' ?{[^}]+}', "repl": ""} # delete content inside {} + +- {"pattern": "[^ !$%',-.0123456789;?ABCDEFGHIJKLMNOPQRSßTUVWXYŸZabcdefghijklmnopqrsẞtuvwxyÿz¡£¿ÀÁÂÃÄÅÆÇÈÉÊÌÍÎÑÒÓÔÕÖØÙÚÜÝàáâãäåæçèéêëìíîïñòóôõöøùúûüýĀāĂ㥹ĆćĊċČčĎďĐđĒēĖėĘęĚěĠġĢģĦħĪīĮįĶķĹĺĻļĽľŁłŃńŅņŇňŐőŒœŔŕŘřŚśŠšŤťŪūŮůŰűŲųŹźŻżŽžȘșȚțΆΈΉΌΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩάέήίαβγδεζηθικλμνξοπρστυφχψωϊόύώЁЄІЇАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяёєіїҐґ€₴₽/:]", "repl": " "} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/cs.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/cs.yaml new file mode 100644 index 00000000..19ea0d69 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/cs.yaml @@ -0,0 +1,27 @@ +- {'pattern': 'ă', 'repl': 'a'} +- {'pattern': 'ğ', 'repl': 'g'} +- {'pattern': 'ş', 'repl': 's'} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "—", "repl": ' '} +- {"pattern": "–", "repl": ' '} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': ' '} + +- {"pattern": "[^ €₽₴$£%?!',.0123456789ABCCDEFGHHIJKLMNOPQRSTUVWXYZabccdefghhijklmnopqrstuvwxyzÁÉÍÓÚÝáéíóúýČčĎďĚěŇňŘřŠšŤťŮůŽž]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/da.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/da.yaml new file mode 100644 index 00000000..d9e3bb20 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/da.yaml @@ -0,0 +1,29 @@ +- {'pattern': 'ó', 'repl': 'o'} +- {'pattern': 'ă', 'repl': 'a'} +- {'pattern': 'ğ', 'repl': 'g'} +- {'pattern': 'ş', 'repl': 's'} +- {'pattern': 'é', 'repl': 'e'} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "—", "repl": ' '} +- {"pattern": "–", "repl": ' '} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': ' '} + +- {"pattern": "[^ €₽₴$£%!$',.?0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÆØÅæøå]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/de.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/de.yaml new file mode 100644 index 00000000..71195701 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/de.yaml @@ -0,0 +1,31 @@ +- {'pattern': 'ă', 'repl': 'a'} +- {'pattern': 'ğ', 'repl': 'g'} +- {'pattern': 'ş', 'repl': 's'} +- {'pattern': 'ó', 'repl': 'o'} +- {'pattern': 'é', 'repl': 'e'} + +- {"pattern": "ß", "repl": "ss"} +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "—", "repl": ' '} +- {"pattern": "–", "repl": ' '} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': ' '} + +# Keep these characters and remove everything else !$',.0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +- {"pattern": "[^ €₽₴$£%?!',.ÄäÖöÜü0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]", "repl": ""} + +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} + diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/el.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/el.yaml new file mode 100644 index 00000000..d3f7cb7f --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/el.yaml @@ -0,0 +1,35 @@ +- {'pattern': 'á', 'repl': 'a'} +- {'pattern': 'é', 'repl': 'e'} +- {'pattern': 'í', 'repl': 'i'} +- {'pattern': 'ó', 'repl': 'o'} +- {'pattern': 'ă', 'repl': 'a'} +- {'pattern': 'ğ', 'repl': 'g'} +- {'pattern': 'ř', 'repl': 'r'} +- {'pattern': 'ş', 'repl': 's'} +- {'pattern': 'š', 'repl': 's'} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "—", "repl": ' '} +- {"pattern": "–", "repl": ' '} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': ' '} + +# In greek question mark is ";" +# Got these from part of fleurs set: άέήίωϊόύώ +- {"pattern": "[^ €₽₴$£%!%$',.;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωΆΈΉΌάέήίωϊόύώ]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/en.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/en.yaml new file mode 100644 index 00000000..5f198c9a --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/en.yaml @@ -0,0 +1,47 @@ +- {'pattern': 'ó', 'repl': 'o'} +- {'pattern': 'ñ', 'repl': 'n'} +- {'pattern': 'é', 'repl': 'e'} +- {'pattern': 'á', 'repl': 'a'} +- {'pattern': 'í', 'repl': 'i'} +- {'pattern': 'ú', 'repl': 'u'} +- {'pattern': 'ü', 'repl': 'u'} +- {'pattern': 'ï', 'repl': 'i'} +- {'pattern': 'ë', 'repl': 'e'} +- {'pattern': 'ô', 'repl': 'o'} +- {'pattern': 'û', 'repl': 'u'} +- {'pattern': 'â', 'repl': 'a'} +- {'pattern': 'ê', 'repl': 'e'} +- {'pattern': 'î', 'repl': 'i'} +- {'pattern': 'ô', 'repl': 'o'} +- {'pattern': 'û', 'repl': 'u'} +- {'pattern': 'ã', 'repl': 'a'} +- {'pattern': 'õ', 'repl': 'o'} +- {'pattern': 'ç', 'repl': 'c'} +- {'pattern': 'ă', 'repl': 'a'} +- {'pattern': 'ğ', 'repl': 'g'} +- {'pattern': 'ş', 'repl': 's'} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "—", "repl": ' '} +- {"pattern": "–", "repl": ' '} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': ' '} + +# Keep these characters and remove everything else !$',.0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +- {"pattern": "[^ €₽₴$£%!$',.?0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/es.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/es.yaml new file mode 100644 index 00000000..4af19681 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/es.yaml @@ -0,0 +1,28 @@ +- {'pattern': 'ă', 'repl': 'a'} +- {'pattern': 'ğ', 'repl': 'g'} +- {'pattern': 'ş', 'repl': 's'} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "—", "repl": ' '} +- {"pattern": "–", "repl": ' '} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': ' '} + +# Keep these characters and remove everything else !$',.0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +- {"pattern": "[^ €₽₴$£%?!$',.¿¡0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZáéíóúüñÁÉÍÓÚÜÑabcdefghijklmnopqrstuvwxyz]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/et.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/et.yaml new file mode 100644 index 00000000..4dd82d8d --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/et.yaml @@ -0,0 +1,31 @@ +- {'pattern': 'ă', 'repl': 'a'} +- {'pattern': 'ğ', 'repl': 'g'} +- {'pattern': 'ş', 'repl': 's'} +- {'pattern': 'é', 'repl': 'e'} +- {'pattern': 'ó', 'repl': 'o'} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "—", "repl": ' '} +- {"pattern": "–", "repl": ' '} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': ' '} + +# Keep these characters and remove everything else !$',.0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +- {"pattern": "[^ €₽₴$£%!',.?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÄÖÜÕäöüõšž]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} + diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/fi.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/fi.yaml new file mode 100644 index 00000000..d5356640 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/fi.yaml @@ -0,0 +1,34 @@ +- {'pattern': 'á', 'repl': 'a'} +- {'pattern': 'é', 'repl': 'e'} +- {'pattern': 'í', 'repl': 'i'} +- {'pattern': 'ó', 'repl': 'o'} +- {'pattern': 'ă', 'repl': 'a'} +- {'pattern': 'ğ', 'repl': 'g'} +- {'pattern': 'ř', 'repl': 'r'} +- {'pattern': 'ş', 'repl': 's'} +- {'pattern': 'š', 'repl': 's'} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "—", "repl": ' '} +- {"pattern": "–", "repl": ' '} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': ' '} + +# Keep these characters and remove everything else !$',.0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +- {"pattern": "[^ €₽₴$£%!',.?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÄäÖö]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/fr.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/fr.yaml new file mode 100644 index 00000000..7dd0d7db --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/fr.yaml @@ -0,0 +1,35 @@ +- {"pattern": "Ä", "repl": "A"} +- {"pattern": "ä", "repl": "a"} +- {"pattern": "Ï", "repl": "I"} +- {"pattern": "Ë", "repl": "E"} +- {"pattern": "Ö", "repl": "O"} +- {"pattern": "ö", "repl": "o"} +- {"pattern": "Ÿ", "repl": "Y"} +- {"pattern": "ÿ", "repl": "y"} +- {"pattern": "Ü", "repl": "U"} +- {"pattern": "ü", "repl": "u"} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "—", "repl": ' '} +- {"pattern": "–", "repl": ' '} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': ' '} + +# Keep these characters and remove everything else !$',.0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +- {"pattern": "[^ €₽₴$£%?!',.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÆŒÀÂÉÎÇàâçèéêëîïóôùûœæ]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/hr.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/hr.yaml new file mode 100644 index 00000000..23cdf981 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/hr.yaml @@ -0,0 +1,30 @@ +- {'pattern': 'ă', 'repl': 'a'} +- {'pattern': 'ğ', 'repl': 'g'} +- {'pattern': 'ş', 'repl': 's'} +- {'pattern': 'ó', 'repl': 'o'} +- {'pattern': 'é', 'repl': 'e'} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "—", "repl": ' '} +- {"pattern": "–", "repl": ' '} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': ' '} + +# Keep these characters and remove everything else !$',.0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +- {"pattern": "[^ €₽₴$£%?!',.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzĆćČčĐ𩹮ž]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/hu.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/hu.yaml new file mode 100644 index 00000000..2e7c8e4c --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/hu.yaml @@ -0,0 +1,25 @@ +- {'pattern': 'ğ', 'repl': 'g'} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "—", "repl": ' '} +- {"pattern": "–", "repl": ' '} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': ' '} + +- {"pattern": "[^ €₽₴$£%!',.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÁÉÍÓÕÖÚÜáéíóõöúüŠšŰűŐő]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/it.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/it.yaml new file mode 100644 index 00000000..15a9296b --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/it.yaml @@ -0,0 +1,31 @@ +- {'pattern': 'ó', 'repl': 'o'} +- {'pattern': 'ă', 'repl': 'a'} +- {'pattern': 'ğ', 'repl': 'g'} +- {'pattern': 'ş', 'repl': 's'} +- {'pattern': 'š', 'repl': 's'} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "—", "repl": ' '} +- {"pattern": "–", "repl": ' '} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': ' '} + +# Keep these characters and remove everything else !$',.0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +- {"pattern": "[^ €₽₴$£%!',.?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÀÈÉÌÒÙàèéìòù]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} + diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/lt.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/lt.yaml new file mode 100644 index 00000000..68e25e1a --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/lt.yaml @@ -0,0 +1,26 @@ +- {'pattern': 'é', 'repl': 'e'} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "–", "repl": "-"} +- {"pattern": "—", "repl": "-"} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': '-'} + +# Keep these characters and remove everything else !$',.0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +- {"pattern": "[^ €₽₴$£%!',.?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzĄąČčĖėĘęĮįŠšŪūŲųŽž-]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} \ No newline at end of file diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/lv.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/lv.yaml new file mode 100644 index 00000000..682b57d9 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/lv.yaml @@ -0,0 +1,26 @@ +- {'pattern': 'é', 'repl': 'e'} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "—", "repl": ' '} +- {"pattern": "–", "repl": ' '} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': ' '} + +# Keep these characters and remove everything else !$',.0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +- {"pattern": "[^ €₽₴$£%!',.?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzĀāČčĒēĢģĪīĶķĻļŅņŠšŪūŽž]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/mt.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/mt.yaml new file mode 100644 index 00000000..f13b8f64 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/mt.yaml @@ -0,0 +1,33 @@ +- {'pattern': 'à', 'repl': 'a'} +- {'pattern': 'è', 'repl': 'e'} +- {'pattern': 'é', 'repl': 'e'} +- {'pattern': 'ó', 'repl': 'o'} +- {'pattern': 'ă', 'repl': 'a'} +- {'pattern': 'ğ', 'repl': 'g'} +- {'pattern': 'ş', 'repl': 's'} + + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "–", "repl": "-"} +- {"pattern": "—", "repl": "-"} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': '-'} + +# Keep these characters and remove everything else !$',.0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +- {"pattern": "[^ €₽₴$£%!',.?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzĊċĠġĦħŻż]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} \ No newline at end of file diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/nl.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/nl.yaml new file mode 100644 index 00000000..3f7669b9 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/nl.yaml @@ -0,0 +1,29 @@ +- {'pattern': 'ă', 'repl': 'a'} +- {'pattern': 'ğ', 'repl': 'g'} +- {'pattern': 'ş', 'repl': 's'} +- {'pattern': 'ñ', 'repl': 'n'} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "—", "repl": ' '} +- {"pattern": "–", "repl": ' '} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': ' '} + +# Keep these characters and remove everything else !$',.0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +- {"pattern": "[^ €₽₴$£%!',.?0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzéëïóü]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} \ No newline at end of file diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/pl.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/pl.yaml new file mode 100644 index 00000000..29f9874e --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/pl.yaml @@ -0,0 +1,30 @@ +- {'pattern': 'ă', 'repl': 'a'} +- {'pattern': 'ğ', 'repl': 'g'} +- {'pattern': 'ş', 'repl': 's'} +- {'pattern': 'ñ', 'repl': 'n'} +- {'pattern': 'é', 'repl': 'e'} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "—", "repl": ' '} +- {"pattern": "–", "repl": ' '} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': ' '} + +# Keep these characters and remove everything else !$',.0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +- {"pattern": "[^ €₽₴$£%!',.?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÓóĄąĆćĘꣳŃńŚśŹźŻż]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} \ No newline at end of file diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/pt.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/pt.yaml new file mode 100644 index 00000000..963f63a9 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/pt.yaml @@ -0,0 +1,25 @@ +- {'pattern': 'ğ', 'repl': 'g'} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "—", "repl": ' '} +- {"pattern": "–", "repl": ' '} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': ' '} + +- {"pattern": "[^ €₽₴$£%!',.?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÀÁÂÃÇÉÊÍÓÔÕÚÜàáâãçéêíóôõúü]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/ro.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/ro.yaml new file mode 100644 index 00000000..505465e2 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/ro.yaml @@ -0,0 +1,28 @@ +- {'pattern': 'ó', 'repl': 'o'} +- {'pattern': 'ğ', 'repl': 'g'} +- {'pattern': 'é', 'repl': 'e'} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "—", "repl": '-'} +- {"pattern": "–", "repl": '-'} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': '-'} + +# Keep these characters and remove everything else !$',.0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +- {"pattern": "[^ €₽₴$£%!',.?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÂÎâîĂăȘșȚț-]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/ru.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/ru.yaml new file mode 100644 index 00000000..a3a777f7 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/ru.yaml @@ -0,0 +1,32 @@ +- {'pattern': 'ă', 'repl': 'a'} +- {'pattern': 'ğ', 'repl': 'g'} +- {'pattern': 'ş', 'repl': 's'} +- {'pattern': 'ñ', 'repl': 'n'} +- {'pattern': 'é', 'repl': 'e'} +- {"pattern": "ё", "repl": "e"} +- {"pattern": "Ё", "repl": "E"} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "–", "repl": "-"} +- {"pattern": "—", "repl": "-"} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': '-'} + +# Keep these characters and remove everything else !$',.0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +- {"pattern": "[^ €₽₴$£%!',.?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё-]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/sk.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/sk.yaml new file mode 100644 index 00000000..923bb5d7 --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/sk.yaml @@ -0,0 +1,26 @@ +- {'pattern': 'ř', 'repl': 'r'} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "—", "repl": ' '} +- {"pattern": "–", "repl": ' '} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': ' '} + +# Keep these characters and remove everything else !$',.0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +- {"pattern": "[^ €₽₴$£%!',.?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÁÄÉÍÓÔÚÝáäéíóôúýČčĎďĹ弾ŇňŔ੹ŤťŽž]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} \ No newline at end of file diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/sl.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/sl.yaml new file mode 100644 index 00000000..7a8564aa --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/sl.yaml @@ -0,0 +1,28 @@ +- {'pattern': 'é', 'repl': 'e'} +- {'pattern': 'ó', 'repl': 'o'} +- {'pattern': 'ğ', 'repl': 'g'} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "—", "repl": ' '} +- {"pattern": "–", "repl": ' '} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': ' '} + +# Keep these characters and remove everything else !$',.0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +- {"pattern": "[^ €₽₴$£%!',.?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzČčŠšŽž]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/sv.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/sv.yaml new file mode 100644 index 00000000..f9afe0da --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/sv.yaml @@ -0,0 +1,30 @@ +- {'pattern': 'é', 'repl': 'e'} +- {'pattern': 'ñ', 'repl': 'n'} +- {'pattern': 'á', 'repl': 'a'} +- {'pattern': 'ă', 'repl': 'a'} +- {'pattern': 'ş', 'repl': 's'} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "—", "repl": ' '} +- {"pattern": "–", "repl": ' '} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': ' '} + +# Keep these characters and remove everything else !$',.0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +- {"pattern": "[^ €₽₴$£%!',.?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÄÅÖäåö]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} \ No newline at end of file diff --git a/dataset_configs/multilingual/yodas2/partials/subregex_params/uk.yaml b/dataset_configs/multilingual/yodas2/partials/subregex_params/uk.yaml new file mode 100644 index 00000000..34468f7e --- /dev/null +++ b/dataset_configs/multilingual/yodas2/partials/subregex_params/uk.yaml @@ -0,0 +1,26 @@ +- {'pattern': 'é', 'repl': 'e'} + +- {"pattern": "’", "repl": "'"} +- {"pattern": "‘", "repl": "'"} +- {"pattern": ";", "repl": ','} +- {"pattern": "–", "repl": "-"} +- {"pattern": "—", "repl": "-"} +- {"pattern": "♫", "repl": ' '} +- {"pattern": "♪", "repl": ' '} +- {"pattern": "♬", "repl": ' '} +- {"pattern": "♩", "repl": ' '} +- {"pattern": "♭", "repl": ' '} +- {"pattern": '\|', "repl": ' '} +- {'pattern': ':', 'repl': ' '} +- {'pattern': '-', 'repl': '-'} + +# Keep these characters and remove everything else !$',.0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +- {"pattern": "[^ €₽₴$£%!',.?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzЄІЇАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЮЯабвгдежзийклмнопрстуфхцчшщьюяєіїҐґ-]", "repl": ""} + +# keep capital letters, lowercase letters, and spaces, ?, !, ., ,, and ' only +- {"pattern": '\s+\.', "repl": "."} +- {"pattern": '\?+', "repl": "?"} +- {"pattern": '\.+', "repl": "."} +- {"pattern": ',+', "repl": ","} +- {"pattern": '!+', "repl": "!"} +- {"pattern": '\s+', "repl": " "} \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile index 3dc68216..e65afd40 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,5 +1,9 @@ FROM nvidia/cuda:12.1.1-cudnn8-devel-ubuntu22.04 +ARG SOURCE +COPY ${SOURCE:-.} /workspace/NeMo-speech-data-processor +RUN rm -rf /workspace/NeMo-speech-data-processor/docker/ + ARG DEBIAN_FRONTEND=noninteractive ENV TZ=America/Los_Angeles @@ -25,11 +29,11 @@ RUN pip install --upgrade pip COPY . /src/NeMo-speech-data-processor RUN rm -rf /src/NeMo-speech-data-processor/.git - WORKDIR /src/NeMo-speech-data-processor #need to install numpy before reqs, even thougth it present in reqs (cause it requred to install [python-sox], otherwise we face an error) +WORKDIR /workspace/NeMo-speech-data-processor RUN pip install numpy -RUN find requirements/ -name "*.txt" -exec pip install -r {} \; +RUN find requirements/ -maxdepth 1 -name "*.txt" -exec pip install -r {} \; # Set working directory back to NeMo-speech-data-processor WORKDIR /src/NeMo-speech-data-processor diff --git a/docker/datasets/Dockerfile.granary_sdp b/docker/datasets/Dockerfile.granary_sdp new file mode 100644 index 00000000..7dffcc70 --- /dev/null +++ b/docker/datasets/Dockerfile.granary_sdp @@ -0,0 +1,43 @@ +FROM nvidia/cuda:12.1.1-cudnn8-devel-ubuntu22.04 + +ARG SOURCE +COPY ${SOURCE:-.} /workspace/NeMo-speech-data-processor +RUN rm -rf /workspace/NeMo-speech-data-processor/docker/ + +ARG DEBIAN_FRONTEND=noninteractive +ENV TZ=America/Los_Angeles + +# Install basics +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + python3 python3-pip python3-dev python-is-python3 \ + build-essential \ + curl \ + ffmpeg \ + git \ + sox \ + libsox-fmt-mp3 \ + unzip \ + wget \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Update pip +RUN pip install --upgrade pip + +#need to install numpy before reqs, even thougth it present in reqs (cause it requred to install [python-sox], otherwise we face an error) +WORKDIR /workspace/NeMo-speech-data-processor +RUN find requirements/ -maxdepth 1 -name "*.txt" -exec pip install --no-cache-dir -r {} \; +RUN pip cache purge && rm -rf /tmp/* ~/.cache/pip + +#install additional requirements for granary data processing +WORKDIR /workspace/NeMo-speech-data-processor +RUN pip install --no-cache-dir -r requirements/datasets/granary.txt +RUN echo "export LD_LIBRARY_PATH=$(python3 -c 'import os; import nvidia.cublas.lib; import nvidia.cudnn.lib; print(os.path.dirname(nvidia.cublas.lib.__file__) + \":\" + os.path.dirname(nvidia.cudnn.lib.__file__))')" >> /etc/bash.bashrc +RUN pip cache purge && rm -rf /tmp/* ~/.cache/pip + +# Set working directory back to NeMo-speech-data-processor +WORKDIR /workspace/NeMo-speech-data-processor + +# Set up entrypoint +CMD ["bash"] \ No newline at end of file diff --git a/docs/gen_docs.py b/docs/gen_docs.py index 856b1948..90b752bb 100644 --- a/docs/gen_docs.py +++ b/docs/gen_docs.py @@ -44,7 +44,7 @@ def gen_docs(): if file.endswith('.yaml'): source_path = os.path.join(root, file) config_path = source_path.replace(config_dir, '')[1:] # removing leading / - if config_path in IGNORE_CONFIGS: + if config_path in IGNORE_CONFIGS or "partials" in Path(config_path).parts: continue destination_path = source_path.replace(config_dir, config_docs_dir).replace('.yaml', '.rst') with open(source_path, "rt", encoding="utf-8") as fin: diff --git a/docs/src/sdp/api.rst b/docs/src/sdp/api.rst index c285c3b8..940192c9 100644 --- a/docs/src/sdp/api.rst +++ b/docs/src/sdp/api.rst @@ -110,6 +110,19 @@ MediaSpeech :annotation: +Yodas2 +'''''''''''' + +.. autodata:: sdp.processors.ListYodas2Data + :annotation: + +.. autodata:: sdp.processors.DownloadYodas2Data + :annotation: + +.. autodata:: sdp.processors.CreateInitialManifestYodas2 + :annotation: + + HuggingFace Datasets '''''''''''''''''''' @@ -122,6 +135,12 @@ YTC Datasets .. autodata:: sdp.processors.datasets.ytc.create_initial_manifest.CreateInitialManifestYTC :annotation: +.. autodata:: sdp.processors.ListRepoFiles + :annotation: + +.. autodata:: sdp.processors.SnapshotDownload + :annotation: + Lhotse processors ################# @@ -139,7 +158,7 @@ Data enrichment ############### The following processors can be used to add additional attributes to the data by -running different NeMo models (e.g., ASR predictions). These attributes are typically +running different models (e.g., ASR predictions). These attributes are typically used in the downstream processing for additional enhancement or filtering. .. autodata:: sdp.processors.ASRInference @@ -167,6 +186,18 @@ used in the downstream processing for additional enhancement or filtering. :annotation: +.. autodata:: sdp.processors.FasterWhisperInference + :annotation: + +.. autodata:: sdp.processors.vLLMInference + :annotation: + +.. autodata:: sdp.processors.FastTextLangIdClassifier + :annotation: + +.. autodata:: sdp.processors.CometoidWMTQualityEstimation + :annotation: + Text-only processors #################### @@ -199,6 +230,9 @@ Data modifications .. autodata:: sdp.processors.CountNumWords :annotation: +.. autodata:: sdp.processors.FilterWithCharacterHistograms + :annotation: + .. autodata:: sdp.processors.NormalizeText :annotation: @@ -292,6 +326,12 @@ Data filtering .. autodata:: sdp.processors.AcceptIfWERLess :annotation: + +.. autodata:: sdp.processors.DetectWhisperHallucinationFeatures + :annotation: + +.. autodata:: sdp.processors.CleanQwenGeneration + :annotation: .. autodata:: sdp.processors.CreateTolokaPool :annotation: @@ -338,6 +378,9 @@ Miscellaneous .. autodata:: sdp.processors.KeepOnlySpecifiedFields :annotation: +.. autodata:: sdp.processors.DropSpecifiedFields + :annotation: + .. autodata:: sdp.processors.GetAudioDuration :annotation: @@ -347,7 +390,7 @@ Miscellaneous .. autodata:: sdp.processors.CreateInitialManifestByExt :annotation: -.. autodata:: sdp.processors.ApplyInnerJoin +.. autodata:: sdp.processors.JoinManifests :annotation: .. autodata:: sdp.processors.CreateCombinedManifests @@ -366,6 +409,21 @@ Miscellaneous :annotation: +.. autodata:: sdp.processors.ListToEntries + :annotation: + +.. autodata:: sdp.processors.LambdaExpression + :annotation: + +.. autodata:: sdp.processors.ExtractTar + :annotation: + +.. autodata:: sdp.processors.RemoveFiles + :annotation: + +.. autodata:: sdp.processors.ConvertToTarredAudioDatasetConfig + :annotation: + .. _sdp-base-classes: Base classes diff --git a/requirements/datasets/granary.txt b/requirements/datasets/granary.txt new file mode 100644 index 00000000..ee221e58 --- /dev/null +++ b/requirements/datasets/granary.txt @@ -0,0 +1,8 @@ +pytorch-lightning +nvidia-cublas-cu12 +nvidia-cudnn-cu12==9.* +faster_whisper +optree>=0.13.0 +vllm +fasttext +pymarian \ No newline at end of file diff --git a/requirements/main.txt b/requirements/main.txt index d133867a..350f15b3 100644 --- a/requirements/main.txt +++ b/requirements/main.txt @@ -9,7 +9,10 @@ omegaconf pandas rarfile regex +soundfile sox +tabulate +termplotlib tqdm gdown webvtt-py @@ -23,3 +26,11 @@ distributed # for some processers, additionally https://github.com/NVIDIA/NeMo is required # for some processers, additionally nemo_text_processing is required # for mcv: apt-get update && apt-get upgrade -y && apt-get install -y sox libsox-fmt-all + +# for FasterWhisperInference processor is required: + # pip install pytorch-lightning nvidia-cublas-cu12 nvidia-cudnn-cu12==9.* faster_whisper + # export LD_LIBRARY_PATH=`python3 -c 'import os; import nvidia.cublas.lib; import nvidia.cudnn.lib; print(os.path.dirname(nvidia.cublas.lib.__file__) + ":" + os.path.dirname(nvidia.cudnn.lib.__file__))'` +# for vLLMInference processor is required: pip install "optree>=0.13.0" vllm +# for FastTextLangIdClassifier processor is required: pip install fasttext +# for CometoidWMTQualityEstimation processor is required: pip install pymarian +# for ConvertToTarredAudioDatasetConfig processor can be additionally required: pip install lhotse "nemo-toolkit[common]" \ No newline at end of file diff --git a/sdp/processors/__init__.py b/sdp/processors/__init__.py index df860331..ae2a3f5f 100644 --- a/sdp/processors/__init__.py +++ b/sdp/processors/__init__.py @@ -14,65 +14,9 @@ # let's import all supported processors here to simplify target specification -from sdp.processors.datasets.coraa.create_initial_manifest import ( - CreateInitialManifestCORAA, -) -from sdp.processors.datasets.coraal import ( - CreateInitialManifestCORAAL, - TrainDevTestSplitCORAAL, -) -from sdp.processors.datasets.fleurs.create_initial_manifest import ( - CreateInitialManifestFleurs, -) -from sdp.processors.datasets.uzbekvoice.create_initial_manifest import ( - CreateInitialManifestUzbekvoice, -) -from sdp.processors.datasets.ksc2.create_initial_manifest import ( - CreateInitialManifestKSC2, -) -from sdp.processors.datasets.lhotse import LhotseImport -from sdp.processors.datasets.librispeech.create_initial_manifest import ( - CreateInitialManifestLibrispeech, -) -from sdp.processors.datasets.masc import ( - CreateInitialManifestMASC, - AggregateSegments, - RegExpVttEntries, - GetCaptionFileSegments -) -from sdp.processors.datasets.mediaspeech.create_initial_manifest import CreateInitialManifestMediaSpeech -from sdp.processors.datasets.mcv.create_initial_manifest import CreateInitialManifestMCV -from sdp.processors.datasets.mls.create_initial_manifest import CreateInitialManifestMLS -from sdp.processors.datasets.mls.restore_pc import RestorePCForMLS -from sdp.processors.datasets.mtedx.create_initial_manifest import ( - CreateInitialManifestMTEDX, -) -from sdp.processors.datasets.slr83.create_initial_manifest import ( - CreateInitialManifestSLR83, - CustomDataSplitSLR83, -) -from sdp.processors.datasets.slr102.create_initial_manifest import ( - CreateInitialManifestSLR102, -) -from sdp.processors.datasets.slr140.create_initial_manifest import ( - CreateInitialManifestSLR140, - CustomDataSplitSLR140, -) -from sdp.processors.datasets.voxpopuli.create_initial_manifest import ( - CreateInitialManifestVoxpopuli, -) -from sdp.processors.datasets.voxpopuli.normalize_from_non_pc_text import ( - NormalizeFromNonPCTextVoxpopuli, -) -from sdp.processors.datasets.ytc.create_initial_manifest import ( - CreateInitialManifestYTC, -) -from sdp.processors.huggingface.speech_recognition import ASRTransformers -from sdp.processors.huggingface.create_initial_manifest import CreateInitialManifestHuggingFace - from sdp.processors.modify_manifest.common import ( AddConstantFields, - ApplyInnerJoin, + JoinManifests, ChangeToRelativePath, CombineSources, DuplicateFields, @@ -80,6 +24,7 @@ RenameFields, SortManifest, SplitOnFixedDuration, + DropSpecifiedFields, ) from sdp.processors.modify_manifest.create_manifest import ( CreateCombinedManifests, @@ -90,16 +35,17 @@ CopyManifestData, CountNumWords, ExtractFromBrackets, - FfmpegConvert, + FilterWithCharacterHistograms, GetAudioDuration, GetWER, InsIfASRInsertion, InverseNormalizeText, + LambdaExpression, + ListToEntries, NormalizeText, MakeSentence, ReadDocxLines, ReadTxtLines, - SoxConvert, SplitLineBySentence, SubIfASRSubstitution, SubMakeLowercase, @@ -126,8 +72,30 @@ from sdp.processors.modify_manifest.make_letters_uppercase_after_period import ( MakeLettersUppercaseAfterPeriod, ) -from sdp.processors.nemo.asr_inference import ASRInference -from sdp.processors.nemo.pc_inference import PCInference +from sdp.processors.manage_files.extract import ExtractTar +from sdp.processors.manage_files.convert_audio import ( + FfmpegConvert, + SoxConvert, +) +from sdp.processors.manage_files.remove import RemoveFiles +from sdp.processors.manage_files.convert_to_tarred_audio_dataset import ConvertToTarredAudioDataset + +from sdp.processors.huggingface.create_initial_manifest import CreateInitialManifestHuggingFace +from sdp.processors.huggingface.huggingface_hub import ListRepoFiles, SnapshotDownload, HfHubDownload + +from sdp.processors.inference.asr.nemo.asr_inference import ASRInference +from sdp.processors.inference.asr.transformers.speech_recognition import ASRTransformers +from sdp.processors.inference.asr.faster_whisper.faster_whisper_inference import FasterWhisperInference +from sdp.processors.inference.asr.post_processing.whisper_hallucinations import DetectWhisperHallucinationFeatures + +from sdp.processors.inference.llm.vllm.vllm import vLLMInference +from sdp.processors.inference.llm.post_processing.qwen_cleaning import CleanQwenGeneration + +from sdp.processors.inference.nlp.nemo.pc_inference import PCInference +from sdp.processors.inference.nlp.fasttext.fasttext import FastTextLangIdClassifier + +from sdp.processors.inference.quality_estimation.pymarian import CometoidWMTQualityEstimation + from sdp.processors.toloka.accept_if import AcceptIfWERLess from sdp.processors.toloka.create_pool import CreateTolokaPool from sdp.processors.toloka.create_project import CreateTolokaProject @@ -135,3 +103,64 @@ from sdp.processors.toloka.create_task_set import CreateTolokaTaskSet from sdp.processors.toloka.download_responses import GetTolokaResults from sdp.processors.toloka.reject_if import RejectIfBanned + +from sdp.processors.datasets.coraa.create_initial_manifest import ( + CreateInitialManifestCORAA, +) +from sdp.processors.datasets.coraal import ( + CreateInitialManifestCORAAL, + TrainDevTestSplitCORAAL, +) +from sdp.processors.datasets.fleurs.create_initial_manifest import ( + CreateInitialManifestFleurs, +) +from sdp.processors.datasets.uzbekvoice.create_initial_manifest import ( + CreateInitialManifestUzbekvoice, +) +from sdp.processors.datasets.ksc2.create_initial_manifest import ( + CreateInitialManifestKSC2, +) +from sdp.processors.datasets.lhotse import LhotseImport +from sdp.processors.datasets.librispeech.create_initial_manifest import ( + CreateInitialManifestLibrispeech, +) +from sdp.processors.datasets.masc import ( + CreateInitialManifestMASC, + AggregateSegments, + RegExpVttEntries, + GetCaptionFileSegments +) +from sdp.processors.datasets.mediaspeech.create_initial_manifest import CreateInitialManifestMediaSpeech +from sdp.processors.datasets.mcv.create_initial_manifest import CreateInitialManifestMCV +from sdp.processors.datasets.mls.create_initial_manifest import CreateInitialManifestMLS +from sdp.processors.datasets.mls.restore_pc import RestorePCForMLS +from sdp.processors.datasets.mtedx.create_initial_manifest import ( + CreateInitialManifestMTEDX, +) +from sdp.processors.datasets.slr83.create_initial_manifest import ( + CreateInitialManifestSLR83, + CustomDataSplitSLR83, +) +from sdp.processors.datasets.slr102.create_initial_manifest import ( + CreateInitialManifestSLR102, +) +from sdp.processors.datasets.slr140.create_initial_manifest import ( + CreateInitialManifestSLR140, + CustomDataSplitSLR140, +) +from sdp.processors.datasets.voxpopuli.create_initial_manifest import ( + CreateInitialManifestVoxpopuli, +) +from sdp.processors.datasets.voxpopuli.normalize_from_non_pc_text import ( + NormalizeFromNonPCTextVoxpopuli, +) +from sdp.processors.datasets.ytc.create_initial_manifest import ( + CreateInitialManifestYTC, +) +from sdp.processors.datasets.yodas2.create_initial_manifest import( + ListYodas2Data, + SnapshotDownloadYodas2Data, + HfHubDownloadYodas2Data, + CreateInitialManifestYodas2, +) +from sdp.processors.datasets.granary import GetGranarysYodas2 \ No newline at end of file diff --git a/sdp/processors/base_processor.py b/sdp/processors/base_processor.py index 6fc22ee8..a4257e53 100644 --- a/sdp/processors/base_processor.py +++ b/sdp/processors/base_processor.py @@ -19,7 +19,6 @@ import time from abc import ABC, abstractmethod from dataclasses import dataclass -from itertools import chain from typing import Any, Dict, List, Optional, Union from tqdm import tqdm diff --git a/sdp/processors/datasets/__init__.py b/sdp/processors/datasets/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/sdp/processors/datasets/granary/create_initial_manifest.py b/sdp/processors/datasets/granary/create_initial_manifest.py new file mode 100644 index 00000000..1c25566d --- /dev/null +++ b/sdp/processors/datasets/granary/create_initial_manifest.py @@ -0,0 +1,79 @@ +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import json +from glob import glob +from tqdm import tqdm +import tempfile + +from sdp.processors.huggingface.huggingface_hub import SnapshotDownload +from sdp.logging import logger + +class GetGranarysYodas2(SnapshotDownload): + AVAILABLE_LANGS = ["bg", "cs", "da", "de", "el", + "en", "es", "et", "fi", "fr", + "hr", "hu", "it", "lt", "lv", + "nl", "pl", "pt", "ro", "ru", + "sk", "sv", "uk"] + + def __init__(self, lang: str, translation: bool = False, **kwargs): + + if lang not in self.AVAILABLE_LANGS: + raise ValueError("") + self.lang = lang + pattern = f"{self.lang}/{self.lang}*.json" + + self.translation = translation + + if self.translation: + if self.lang == "en": + logger.warning(f'There are no translations for `en` language.') + self.translation = False + else: + pattern = f"Translation/{self.lang}_/{self.lang}*.jsonl" + + if 'snapshot_download_args' not in kwargs: + kwargs['snapshot_download_args'] = dict() + + kwargs['snapshot_download_args']['repo_id']="YODASEnj/YDS" + kwargs['snapshot_download_args']['repo_type']="dataset" + kwargs['snapshot_download_args']['allow_patterns']=pattern + + super().__init__(**kwargs) + + def process(self): + with tempfile.TemporaryDirectory() as tmp_dir: + self.snapshot_download_args["local_dir"] = tmp_dir + super().process() + + with open(self.output_manifest_file, 'w', encoding='utf8') as fout: + for manifest_filepath in sorted(glob(f"{tmp_dir}/{self.snapshot_download_args['allow_patterns']}")): + with open(manifest_filepath, 'r', encoding='utf8') as fin: + for line in tqdm(fin, desc = f'Processing {os.path.basename(manifest_filepath)}'): + sample = json.loads(line) + new_sample = dict(source_lang = self.lang, + target_lang = self.lang, + yodas_id = sample['wav_id'], + offset = sample['start_time'], + duration = sample['duration'], + text = sample['text'], + answer = sample['text'] + ) + + if self.translation: + new_sample['target_lang'] = "en" + new_sample['answer'] = sample['translation_en'] + + fout.writelines(json.dumps(new_sample) + '\n') \ No newline at end of file diff --git a/sdp/processors/datasets/yodas2/create_initial_manifest.py b/sdp/processors/datasets/yodas2/create_initial_manifest.py new file mode 100644 index 00000000..b08cdf3e --- /dev/null +++ b/sdp/processors/datasets/yodas2/create_initial_manifest.py @@ -0,0 +1,399 @@ +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +from pathlib import Path +import json +from tqdm import tqdm +import tempfile +import importlib.util + +from sdp.processors import ListToEntries +from sdp.processors.huggingface.huggingface_hub import ListRepoFiles, SnapshotDownload, HfHubDownload +from sdp.logging import logger + + +class ListYodas2Data(ListRepoFiles): + """ + Processor for generating a manifest of the YODAS2 dataset stored on the Hugging Face Hub. + + This processor supports two modes: + 1. Using the `meta.py` file from the dataset repo (if `use_metadata=True`), which provides + structured metadata including the number of shards per language subset. + + 2. Parsing the repository's file list directly to infer the manifest structure (default mode). + + Args: + use_metadata (bool): Whether to use `meta.py` to generate the manifest (default: False). + **kwargs: Passed to the parent class `sdp.processors.ListRepoFiles`, including Hugging Face repo config. + + Returns: + A line-delimited JSON manifest, where each line represents information about a YODAS2 dataset shard and + includes keys pointing to the audio files (in .tar.gz format), transcriptions (in .json format), and + durations (in .txt format) stored in the repository. + """ + + def __init__(self, use_metadata: bool = False, **kwargs): + # Initialize parent class with hardcoded repo_id and repo_type for YODAS2 + super().__init__(repo_id="espnet/yodas2", repo_type="dataset", **kwargs) + self.use_metadata = use_metadata + + def process(self): + from huggingface_hub import hf_hub_download + + """ + Main entry point for generating the YODAS2 manifest. + + If `use_metadata=True`, it uses the `meta.py` file to generate expected paths. + Otherwise, it lists all files from Hugging Face and organizes them by language and shard. + The final manifest is written as line-delimited JSON. + """ + if self.use_metadata: + metadata = None + with tempfile.TemporaryDirectory() as tmp_dir: + # Download the meta.py script containing shard information + yodas_metafile = hf_hub_download( + repo_id="espnet/yodas2", + filename="meta.py", + repo_type="dataset", + local_dir=tmp_dir + ) + # Dynamically import meta.py + spec = importlib.util.spec_from_file_location("script", yodas_metafile) + metadata = importlib.util.module_from_spec(spec) + spec.loader.exec_module(metadata) + + # Write the manifest based on metadata.lang2shard_cnt + with open(self.output_manifest_file, 'w', encoding='utf8') as fout: + for lang_subset in sorted(metadata.lang2shard_cnt.keys()): + for shard_no in range(metadata.lang2shard_cnt[lang_subset]): + shard_id = str(shard_no).zfill(8) + data_entry = { + "lang_subset": lang_subset, + "shard_id": shard_id, + "audio_key": f"data/{lang_subset}/audio/{shard_id}.tar.gz", + "duration_key": f"data/{lang_subset}/duration/{shard_id}.txt", + "text_key": f"data/{lang_subset}/text/{shard_id}.json", + } + line = json.dumps(data_entry) + fout.writelines(f"{line}\n") + else: + logger.info("Receiving files list of espnet/yodas2 dataset from Hugging Face...") + self.list_repo_files() + logger.info("Metadata has been successfully received. Aggregating filenames into shards...") + + lang2shard_files = {} + + # Parse each file path and organize by language subset and shard + for file in tqdm(self.files): + if not file.startswith("data/"): + continue + + path = Path(file) + lang_subset = path.parts[1] # e.g., "en000" + if lang_subset not in lang2shard_files: + lang2shard_files[lang_subset] = {} + lang_shards = lang2shard_files[lang_subset] + + shard_no = path.parts[3].split('.')[0] # e.g., "00000001" + if shard_no not in lang_shards: + lang_shards[shard_no] = {} + shard_files = lang_shards[shard_no] + + data_type = path.parts[2] # e.g., "audio", "duration", "text" + shard_files[data_type] = file + + logger.info("Writing data into manifest...") + + # Write aggregated entries to manifest + with open(self.output_manifest_file, 'w', encoding='utf8') as fout: + for lang_subset in sorted(lang2shard_files.keys()): + lang_subset_shards = lang2shard_files[lang_subset] + for shard_id in sorted(lang_subset_shards.keys()): + data_entry = { + "lang_subset": lang_subset, + "shard_id": shard_id, + } + + # Add keys for each data type (audio_key, duration_key, etc.) + shard_data = lang_subset_shards[shard_id] + for data_type in sorted(shard_data.keys()): + data_entry[f"{data_type}_key"] = shard_data[data_type] + + line = json.dumps(data_entry) + fout.writelines(f"{line}\n") + + logger.info("Metadata successfully saved!") + + +class SnapshotDownloadYodas2Data(SnapshotDownload): + """ + A specialized processor for downloading the YODAS2 dataset from Hugging Face + and updating the input manifest with local file paths to the downloaded files. + + This class: + - Loads an input manifest that contains HF repo-relative paths to audio, text, and duration files. + - Downloads only the referenced files using Hugging Face `snapshot_download` with `allow_patterns`. + - Updates the manifest with paths to the locally downloaded files (under keys `local_audio`, `local_duration`, `local_text`). + + Args: + output_manifest_file (str): Path to write the updated output manifest file. + input_manifest_file (str): Path to the input manifest listing the files to fetch. + Each line must be a JSON object that contains the following **optional but expected** fields: + + - "audio_key" (str): Relative path in the Hugging Face dataset repository to the audio file. + - "duration_key" (str): Relative path to a file containing the duration of the audio sample. + - "text_key" (str): Relative path to the transcription or label file for the audio sample. + + At least one of these keys should be present in each entry. These keys are used to determine + which files to download from the Hugging Face dataset and to map them to local files after download. + + **kwargs: Additional arguments passed to the base SnapshotDownload processor. + + Returns: + A line-delimited JSON manifest, where each line represents a sample entry + and contains absolute local paths to the audio, duration, and text files. + + .. admonition:: Example + + Input line:: + + { + "lang_subset": "en000", + "shard_id": "00000000", + "audio_key": "data/en000/audio/00000000.tar.gz", + "duration_key": "data/en000/duration/00000000.txt", + "text_key": "data/en000/text/00000000.json" + } + + Output line:: + + { + "lang_subset": "en000", + "shard_id": "00000000", + "audio_key": "data/en000/audio/00000000.tar.gz", + "duration_key": "data/en000/duration/00000000.txt", + "text_key": "data/en000/text/00000000.json", + "local_audio": "/path/to/data/en000/audio/00000000.tar.gz", + "local_duration": "/path/to/data/en000/duration/00000000.txt"} + "local_text": "/path/to/data/en000/text/00000000.json" + } + + """ + + def __init__(self, **kwargs): + # Hardcoded to download the espnet/yodas2 dataset from Hugging Face + if not 'snapshot_download_args' in kwargs: + kwargs['snapshot_download_args'] = dict() + kwargs['snapshot_download_args']['repo_id'] = 'espnet/yodas2' + kwargs['snapshot_download_args']['repo_type'] = 'dataset' + + super().__init__(**kwargs) + + def write_output_manifest_file(self): + """ + Write a new manifest file that includes local paths to audio, text, and duration files. + + For each line in the input manifest, checks for keys `audio_key`, `duration_key`, and `text_key`. + If the corresponding file exists locally after download, adds the local path under + `local_audio`, `local_duration`, and `local_text`, respectively. + """ + + # Open input manifest for reading and output manifest for writing + with open(self.input_manifest_file, 'r', encoding='utf8') as fin, open(self.output_manifest_file, 'w', encoding='utf8') as fout: + for line in fin: + sample = json.loads(line) + + # Try to find and attach local paths for each possible file type + audio_file = sample.get('audio_key') + if audio_file: + local_audio_file = os.path.join(self.local_dir, audio_file) + if os.path.exists(local_audio_file): + sample['local_audio'] = local_audio_file + + duration_file = sample.get('duration_key') + if duration_file: + local_duration_file = os.path.join(self.local_dir, duration_file) + if os.path.exists(local_duration_file): + sample['local_duration'] = local_duration_file + + text_file = sample.get('text_key') + if text_file: + local_text_file = os.path.join(self.local_dir, text_file) + if os.path.exists(local_text_file): + sample['local_text'] = local_text_file + + # Write the modified sample to the output manifest + line = json.dumps(sample) + fout.writelines(f'{line}\n') + + def process(self): + """ + Main processing function: collects the list of files to download, + performs the download, and then writes the output manifest. + + This method: + - Scans the input manifest to extract all relevant repo-relative file paths. + - Adds them to the `allow_patterns` argument of `snapshot_download_kwargs`. + - Triggers the download of only the needed files. + - Updates the manifest with local paths. + """ + allow_patterns = [] + + # Parse input manifest to extract all file paths to allow in the snapshot + with open(self.input_manifest_file, 'r', encoding='utf8') as fin: + for line in fin: + sample = json.loads(line) + + audio_file = sample.get('audio_key') + if audio_file: + allow_patterns.append(audio_file) + + duration_file = sample.get('duration_key') + if duration_file: + allow_patterns.append(duration_file) + + text_file = sample.get('text_key') + if text_file: + allow_patterns.append(text_file) + + # Restrict snapshot download to only needed files + self.snapshot_download_kwargs['allow_patterns'] = allow_patterns + + # Download the snapshot and write updated manifest + self.download() + self.write_output_manifest_file() + + +class HfHubDownloadYodas2Data(HfHubDownload): + def __init__(self, filename_field: str = 'audio_key', output_filepath_field = 'local_audio', **kwargs): + if not 'hf_hub_download_args' in kwargs: + kwargs['hf_hub_download_args'] = dict() + kwargs['hf_hub_download_args']['repo_id'] = 'espnet/yodas2' + kwargs['hf_hub_download_args']['repo_type'] = 'dataset' + + super().__init__(filename_field = filename_field, output_filepath_field = output_filepath_field, **kwargs) + + def process(self): + super().process() + +class CreateInitialManifestYodas2(ListToEntries): + """ + A dataset processor specialized for the YODAS2 dataset. + + This processor extends ``ListToEntries`` to: + + - Expand each input record that contains a list of audio items (e.g., under a ``shards`` or ``files`` field). + - Append duration and YODAS ID metadata to each resulting entry using a provided durations file. + + Each input entry must include a field (e.g., ``local_duration``) pointing to a `.txt` file + with lines in the format: + + .. code-block:: text + + + + Example input line: + + .. code-block:: json + + { + "lang_subset": "en000", + "shard_id": "00000000", + "audio_key": "data/en000/audio/00000000.tar.gz", + "duration_key": "data/en000/duration/00000000.txt", + "text_key": "data/en000/text/00000000.json", + "src_lang": "en", + "local_audio": "/data3/sdp_test/en/data/en000/audio/00000000.tar.gz", + "local_duration": "/data3/sdp_test/en/data/en000/duration/00000000.txt", + "extracted_audios": [ + "/path/to/data/en000/00000000/YuseO8GhcWk.wav", + "/path/to/data/en000/00000000/Y9zJ8mT5Bou.wav" + ] + } + + Args: + **kwargs: Passed directly to the ``sdp.processors.ListToEntries`` base processor. + + Returns: + A manifest where each entry corresponds to one YODAS2 sample with the following structure: + + .. code-block:: json + + { + "lang_subset": "en000", + "shard_id": "00000000", + "src_lang": "en", + "source_audio_filepath": "/path/to/data/en000/00000000/YuseO8GhcWk.wav", + "yodas_id": "YuseO8GhcWk", + "duration": 216.9 + } + """ + def __init__(self, **kwargs): + # Initialize with ListToEntries configuration + super().__init__(**kwargs) + + def get_samples_durations(self, durations_filepath: str): + """ + Parse durations file into a dict mapping yodas_id -> duration. + + Args: + durations_filepath (str): Path to durations.txt file, where each line + contains " ". + + Returns: + dict[str, float]: Mapping from yodas_id to duration. + """ + durations = dict() + with open(durations_filepath, 'r') as durations_txt: + for line in durations_txt: + yodas_id, duration = line.strip().split() + durations[yodas_id] = float(duration) + return durations + + def process_dataset_entry(self, data_entry): + """ + Process a single dataset entry. + + - Reads durations file from the entry + - Expands list field using base ListToEntries + - Extracts `yodas_id` from audio path and adds `duration` if found + + Args: + data_entry (dict): Original manifest entry with a list field and a pointer + to a local durations.txt file. + + Returns: + List[DataEntry]: Processed and filtered list of entries with yodas_id and duration. + """ + # Load duration metadata for current group of items + durations = self.get_samples_durations(data_entry['local_duration']) + + # Expand the list of items into individual entries (inherited logic) + data_entries = super().process_dataset_entry(data_entry) + + yodas_entries = [] + for entry in data_entries: + # Extract YODAS ID from filename (e.g., "YABC1234" from "YABC1234.wav") + yodas_id = os.path.basename(entry.data['source_audio_filepath']).split('.')[0] + entry.data['yodas_id'] = yodas_id + + # Attach duration if available + if yodas_id in durations: + entry.data['duration'] = durations[yodas_id] + yodas_entries.append(entry) + else: + logger.warning(f'Skipping `{yodas_id}` because there is no duration info in metadata.') + + return yodas_entries \ No newline at end of file diff --git a/sdp/processors/huggingface/huggingface_hub.py b/sdp/processors/huggingface/huggingface_hub.py new file mode 100644 index 00000000..c5a5521c --- /dev/null +++ b/sdp/processors/huggingface/huggingface_hub.py @@ -0,0 +1,171 @@ +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import os +from typing import Dict + +from tqdm.contrib.concurrent import process_map + +from sdp.processors.base_processor import BaseProcessor, BaseParallelProcessor + +def _hf_hub_download(kwargs): + from huggingface_hub import hf_hub_download + return hf_hub_download(**kwargs) + +class ListRepoFiles(BaseProcessor): + """ + Processor that lists files in a Hugging Face Hub repository and writes them + into a JSON manifest file. + + Each line in the output manifest is a JSON object with the key defined by `file_key` + and value being a file path from the repository. + + Args: + output_manifest_file (str): Path to write the output manifest file. + file_key (str): The key name to use in each manifest entry (default: "file_key"). + **list_repo_files_kwargs: Keyword arguments forwarded to `huggingface_hub.list_repo_files()`. + + See also: + https://huggingface.co/docs/huggingface_hub/v0.8.0/en/package_reference/hf_api#huggingface_hub.HfApi.list_repo_files + + Returns: + A line-delimited JSON manifest where each line looks like: + ``{"file_key": "path/to/file.ext"}`` + """ + + def __init__( + self, + output_manifest_file: str, + file_key: str = "file_key", + **list_repo_files_kwargs, + ): + super().__init__(output_manifest_file=output_manifest_file) + self.list_repo_files_kwargs = list_repo_files_kwargs + self.file_key = file_key + + def list_repo_files(self): + """ + Retrieve the list of files from a Hugging Face repository. + """ + from huggingface_hub import list_repo_files + + self.files = list_repo_files(**self.list_repo_files_kwargs) + + def write_output_manifest_file(self): + """ + Write the list of repo files to the output manifest, one file per line as JSON. + """ + with open(self.output_manifest_file, 'w', encoding='utf8') as fout: + for file in self.files: + line = json.dumps({self.file_key: file}) + fout.writelines(f'{line}\n') # Fixed typo: was `lines`, should be `line` + + def process(self): + """ + Main processing entrypoint: get repo files and write to manifest. + """ + self.list_repo_files() + self.write_output_manifest_file() + + +class SnapshotDownload(BaseProcessor): + """ + Processor that downloads a snapshot of a Hugging Face repository to a local directory + and writes the local folder path to a JSON manifest file. + + Args: + output_manifest_file (str): Path to write the output manifest file. + input_manifest_file (str, optional): Path to input manifest (not used in this processor). + **snapshot_download_kwargs: Keyword arguments forwarded to `huggingface_hub.snapshot_download()`. + + See also: + https://huggingface.co/docs/huggingface_hub/v0.30.2/en/package_reference/file_download#huggingface_hub.snapshot_download + + Returns: + A JSON file containing one line: + ``{"destination_dir": "/path/to/downloaded/repo"}`` + """ + + def __init__( + self, + output_filepath_field: str = "downloaded", + snapshot_download_args: Dict = {}, + **kwargs, + ): + super().__init__(**kwargs) + self.output_filepath_field = output_filepath_field + self.snapshot_download_args = snapshot_download_args + + def process(self): + os.makedirs(os.path.dirname(self.output_manifest_file), exist_ok = True) + + """ + Main processing entrypoint: download repo and write path to manifest. + """ + from huggingface_hub import snapshot_download + + self.local_dir = snapshot_download(**self.snapshot_download_args) + + with open(self.output_manifest_file, 'w', encoding='utf8') as fout: + fout.writelines(json.dumps({self.output_filepath_field : self.local_dir})) + + +class HfHubDownload(BaseParallelProcessor): + def __init__( + self, + filename_field: str, + output_filepath_field: str = "downloaded", + hf_hub_download_args: Dict = {}, + **kwargs + ): + super().__init__(**kwargs) + self.filename_field = filename_field + self.output_filepath_field = output_filepath_field + self.hf_hub_download_args = hf_hub_download_args + + def process(self): + self.prepare() + os.makedirs(os.path.dirname(self.output_manifest_file), exist_ok=True) + + with open(self.output_manifest_file, "wt", encoding="utf8") as fout: + for manifest_chunk in self._chunk_manifest(): + # Подготовим список задач + download_tasks = [ + { + **self.hf_hub_download_args, + "filename": entry[self.filename_field] + } + for entry in manifest_chunk + ] + + # Параллельная загрузка с учётом max_workers и chunksize + results = process_map( + _hf_hub_download, + download_tasks, + max_workers=self.max_workers, + chunksize=self.chunksize, + ) + + # Сопоставим обратно результаты с входными entry + for entry, local_path in zip(manifest_chunk, results): + entry[self.output_filepath_field] = local_path + json.dump(entry, fout, ensure_ascii=False) + fout.write("\n") + self.number_of_entries += 1 + + self.finalize(self.test_cases) + + def process_dataset_entry(self, data_entry): + pass \ No newline at end of file diff --git a/sdp/processors/inference/asr/faster_whisper/faster_whisper_inference.py b/sdp/processors/inference/asr/faster_whisper/faster_whisper_inference.py new file mode 100644 index 00000000..35aa1e77 --- /dev/null +++ b/sdp/processors/inference/asr/faster_whisper/faster_whisper_inference.py @@ -0,0 +1,483 @@ +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import os +import json +from copy import deepcopy +from tqdm import tqdm +import librosa +from dataclasses import dataclass, field, asdict, is_dataclass +from typing import List, Optional, Any, Dict +from omegaconf import OmegaConf, MISSING + +from sdp.logging import logger +from multiprocessing import Pool +import traceback + +from sdp.processors.base_processor import BaseProcessor + +""" +This module implements `FasterWhisperInference`, a multiprocessing-compatible audio transcription +processor using the FasterWhisper library. + +It reads an input manifest, runs inference on available devices (GPU/CPU), and outputs predictions, +including optional timestamp and word-level information. + +Classes: + - InferenceConfig: Configuration for whisper decoding and inference behavior. + - ModelConfig: Configuration for the Whisper model loading. + - DatasetConfig: Configuration for dataset input/output handling. + - WhisperInferenceConfig: Combined config container. + - FasterWhisperInference: Main processor class for transcribing input audio files in parallel. +""" + +def serialize(obj): + """ + Recursively serializes a dataclass, list, or dict to a JSON-compatible structure. + + Args: + obj (Any): Object to serialize (dataclass, list, or dict). + + Returns: + JSON-serializable version of the object. + """ + if is_dataclass(obj): + return asdict(obj) + elif isinstance(obj, list): + return [serialize(item) for item in obj] + elif isinstance(obj, dict): + return {k: serialize(v) for k, v in obj.items()} + return obj + +@dataclass +class InferenceConfig: + language: Optional[str] = None + task: str = "transcribe" + log_progress: bool = False + beam_size: int = 5 + best_of: int = 5 + patience: float = 1 + length_penalty: float = 1 + repetition_penalty: float = 1 + no_repeat_ngram_size: int = 0 + temperature: List[float] = field(default_factory=lambda: [0.0, 0.2, 0.4, 0.6, 0.8, 1.0]) + compression_ratio_threshold: Optional[float] = 2.4 + log_prob_threshold: Optional[float] = -1.0 + no_speech_threshold: Optional[float] = 0.6 + condition_on_previous_text: bool = True + prompt_reset_on_temperature: float = 0.5 + initial_prompt: Optional[Any] = None + prefix: Optional[str] = None + suppress_blank: bool = True + suppress_tokens: Optional[List[int]] = field(default_factory=lambda: [-1]) + without_timestamps: bool = True + max_initial_timestamp: float = 1.0 + word_timestamps: bool = False + prepend_punctuations: str = "\"'“¿([{-" + append_punctuations: str = "\"'.。,,!!??::”)]}、" + multilingual: bool = False + vad_filter: bool = True + + try: + from faster_whisper.vad import VadOptions + vad_parameters: Optional[VadOptions] = None + except ModuleNotFoundError: + pass + + max_new_tokens: Optional[int] = None + chunk_length: Optional[int] = None + clip_timestamps: Optional[Any] = "0" + hallucination_silence_threshold: Optional[float] = None + hotwords: Optional[str] = None + language_detection_threshold: Optional[float] = 0.5 + language_detection_segments: int = 1 + +@dataclass +class ModelConfig: + model_size_or_path: str = MISSING + device: str = "auto" + device_index: Optional[List[int]] = field(default_factory=lambda: [0]) + compute_type: str = "default" + cpu_threads: int = 0 + num_workers: int = 1 + download_root: Optional[str] = None + local_files_only: bool = False + files: Optional[dict] = None + + +@dataclass +class DatasetConfig: + manifest_filepath: str = MISSING + output_dir: str = MISSING + skip_corrupted: bool = False + save_timestamps_separately: bool = True + offset: bool = False + + +@dataclass +class WhisperInferenceConfig: + model: ModelConfig = field(default_factory=lambda: ModelConfig()) + dataset: DatasetConfig = field(default_factory=lambda: DatasetConfig()) + inference: InferenceConfig = field(default_factory=lambda: InferenceConfig()) + + +class FasterWhisperInference(BaseProcessor): + """ + Processor that performs parallel audio transcription using the FasterWhisper model. + + This class reads a manifest of audio files, transcribes them using multiprocessing + (each device or CPU thread handles a portion), and writes results in a NeMo-compatible manifest. + + Args: + input_manifest_file (str): Path to the input manifest. + output_manifest_file (Optional[str]): Path to the output manifest (default: `/predictions_all.json`). + model_size_or_path (str): Whisper model path or model name (e.g., 'base', 'medium'). + device (str): Device type to use ('auto', 'cuda', or 'cpu'). + num_devices (int): Number of workers/devices to use (-1 = all available). + model_download_root (Optional[str]): Directory where model checkpoints will be downloaded. + output_dir (Optional[str]): Directory to store output predictions and timestamps. + skip_corrupted_audios (bool): Whether to skip audio files that raise exceptions. + save_timestamps_separately (bool): If True, saves segment/word timestamps as separate files. + slice_by_offset (bool): If True, slices audio using offset/duration before inference. + inference (Optional[Dict]): Additional inference parameters for Whisper. + language_detection_only (bool): If True, only perform language detection. + in_memory_chunksize (int): Number of samples to load per worker at once. + audio_filepath_field (str): Name of the field in manifest pointing to audio path. + + Returns: + A final merged manifest file where each line corresponds to the transcription result of an input audio sample. + The manifest is assembled from multiple per-worker (rank) manifest files, each produced by a separate device or process. + + Each entry contains the following fields: + + - ``language`` (str, optional): Detected language (if language detection is enabled). + - ``language_probability`` (float, optional): Confidence score of detected language. + - ``pred_text`` (str): Final transcribed text obtained by concatenating all segment texts. + + One of the following timestamp representations will also be included, depending on the value of `save_timestamps_separately`: + + - If ``save_timestamps_separately=False``: + - ``segments`` (List[Dict]): List of segment dictionaries with start/end timestamps and transcribed text. + + - If ``save_timestamps_separately=True``: + - ``segments`` (str): Path to a JSON file containing segment-level timestamps. + - ``words`` (str, optional): Path to a JSON file containing word-level timestamps (if `word_timestamps=True`). + + The final combined manifest is written to ``output_manifest_file``, which defaults to ``/predictions_all.json``. + + .. note:: + Make sure to install the following packages before using this processor: + + pip install pytorch-lightning nvidia-cublas-cu12 nvidia-cudnn-cu12==9.* faster_whisper + + Additionally, ensure that the dynamic libraries for cuBLAS and cuDNN are discoverable at runtime: + + export LD_LIBRARY_PATH=`python3 -c 'import os; import nvidia.cublas.lib; import nvidia.cudnn.lib; print(os.path.dirname(nvidia.cublas.lib.__file__) + ":" + os.path.dirname(nvidia.cudnn.lib.__file__))'` + + This is required for CUDA backend components to function correctly when using FasterWhisper with GPU acceleration. + + For detailed configuration options and advanced usage of FasterWhisper, refer to the official repository: + https://github.com/SYSTRAN/faster-whisper + + """ + def __init__(self, + input_manifest_file: str, + output_manifest_file: Optional[str] = None, + model_size_or_path: str = "base", + device: str = "auto", + num_devices: int = -1, + compute_type: str = "default", + model_download_root: Optional[str] = None, + output_dir: Optional[str] = None, + skip_corrupted_audios: bool = False, + save_timestamps_separately: bool = True, + slice_by_offset: bool = False, + inference: Optional[Dict] = {}, + language_detection_only: bool = False, + in_memory_chunksize: int = 100000, + audio_filepath_field: str = 'audio_filepath', + ): + + super().__init__(input_manifest_file = input_manifest_file, + output_manifest_file = output_manifest_file, + ) + + #DatasetConfig setup + if not self.output_manifest_file and not output_dir: + raise ValueError("Either `output_manifest_file` or `output_dir` must be provided.") + + if not output_dir: + output_dir = os.path.splitext(self.output_manifest_file)[0] + + if not self.output_manifest_file: + self.output_manifest_file = os.path.join(output_dir, 'predictions_all.json') + + dataset_cfg = DatasetConfig(manifest_filepath = self.input_manifest_file, + output_dir = output_dir, + skip_corrupted = skip_corrupted_audios, + save_timestamps_separately = save_timestamps_separately, + offset = slice_by_offset) + + #InferenceConfig setup + inference_cfg = OmegaConf.structured(InferenceConfig(**inference)) + + #ModelConfig setup + device, device_ids = self.setup_devices(device, num_devices) + self.device_ids = device_ids + model_cfg = ModelConfig(model_size_or_path = model_size_or_path, + device = device, compute_type = compute_type, + download_root = model_download_root) + + #GeneralConfig setup + self.config = WhisperInferenceConfig(model=model_cfg, + dataset=dataset_cfg, + inference=inference_cfg, + ) + + #Additional args + self.audio_filepath_field = audio_filepath_field + self.language_detection_only = language_detection_only + self.in_memory_chunksize = in_memory_chunksize + + @staticmethod + def setup_devices(device: str = "auto", num_devices: int = -1): + """ + Determines device type and number of workers to use for inference. + + Returns: + Tuple[str, List[int]]: Selected device type and list of device indices. + """ + try: + import torch + TORCH_AVAILABLE = True + except ImportError: + TORCH_AVAILABLE = False + + if device in ["cuda", "auto"] and TORCH_AVAILABLE: + cuda_available_workers = torch.cuda.device_count() + if cuda_available_workers == 0: + if device == "cuda": + raise RuntimeError("GPU was requested, but no CUDA devices are available.") + else: + logger.warning("No GPU found in auto mode — switching to CPU.") + device = "cpu" + else: + logger.info("CUDA devices found. GPU will be used as workers.") + device = "cuda" + elif device == "cpu": + logger.info("CPU will be used as workers.") + else: + raise ValueError(f"Invalid device type: {device}") + + if device == "cuda": + max_available_workers = cuda_available_workers + else: + max_available_workers = os.cpu_count() + + if num_devices < -1 or num_devices == 0: + raise ValueError(f"Invalid number of workers: {num_devices}.") + elif num_devices == -1: + workers = max_available_workers + logger.info(f"Using {workers} {device.upper()} worker(s).") + elif num_devices > max_available_workers: + workers = max_available_workers + logger.warning(f"Requested {num_devices} {device.upper()} workers, but only {max_available_workers} {device.upper()} available — using {workers}.") + else: + workers = num_devices + logger.info(f"Using {workers} {device.upper()} worker(s).") + + device_ids = list(range(workers)) + return device, device_ids + + def prepare(self): + """ + Creates output directories required for storing prediction and timestamp files. + """ + os.makedirs(self.config.dataset.output_dir, exist_ok = True) + if self.config.dataset.save_timestamps_separately: + os.makedirs(os.path.join(self.config.dataset.output_dir, "segments"), exist_ok = True) + if self.config.inference.word_timestamps: + os.makedirs(os.path.join(self.config.dataset.output_dir, "words"), exist_ok = True) + + def _chunk_manifest(self): + """Splits the manifest into smaller chunks defined by ``in_memory_chunksize``.""" + manifest_chunk = [] + for idx, data_entry in enumerate(self.read_manifest(), 1): + manifest_chunk.append(data_entry) + if idx % self.in_memory_chunksize == 0: + yield manifest_chunk + manifest_chunk = [] + if manifest_chunk: + yield manifest_chunk + + def read_manifest(self): + """Reading the input manifest file.""" + if not self.input_manifest_file: + raise NotImplementedError("Override this method if no input manifest file is used") + with open(self.input_manifest_file, "rt", encoding="utf8") as fin: + for line in fin: + yield json.loads(line) + + def get_entries_for_device(self, device_id: int): + """ + Yields manifest entries assigned to a given device. + + Uses round-robin assignment of sorted entries by duration. + """ + for chunk in self._chunk_manifest(): + chunk.sort(key=lambda entry: entry["duration"]) + batch = chunk[device_id::len(self.device_ids)] + for entry in batch: + yield entry + + def get_audio_segment(self, audio_filepath: str, offset: float, duration: float): + """Loads a segment of audio based on offset and duration.""" + audio, sr = librosa.load(audio_filepath, sr=None) + start_sample = int(offset * sr) + end_sample = int((offset + duration) * sr) + audio_segment = audio[start_sample : end_sample] + return audio_segment + + def write_timestamps(self, filename: str, segments: List[Dict]): + """Saves timestamp information (segments and optionally word-level) to separate files.""" + + output_segments_filepath = os.path.join(self.config.dataset.output_dir, 'segments', f'{filename}.json') + sample_words = [] + with open(output_segments_filepath, 'w', encoding = 'utf8') as output_manifest: + for segment in segments: + words = segment.pop('words') + if self.config.inference.word_timestamps: + for word in words: + word['segment_id'] = segment['id'] + sample_words.append(word) + + line = json.dumps(segment) + output_manifest.writelines(f'{line}\n') + + def write_words(words: List[Dict]): + output_manifest_filepath = os.path.join(self.config.dataset.output_dir, 'words', f'{filename}.json') + with open(output_manifest_filepath, 'w', encoding = 'utf8') as output_manifest: + for word in words: + line = json.dumps(word) + output_manifest.writelines(f'{line}\n') + return output_manifest_filepath + + output_words_filepath = None + if self.config.inference.word_timestamps: + output_words_filepath = write_words(output_words_filepath, sample_words) + + return dict(segments = output_segments_filepath, words = output_words_filepath) + + def transcribe(self, device_id: int): + """"" + Transcribes all samples assigned to a given device. + + Loads the Whisper model, reads samples, performs language detection or full transcription, + and writes predictions to a device-specific output file. + """ + + from faster_whisper import WhisperModel + from faster_whisper.audio import decode_audio + + model_cfg = deepcopy(self.config.model) + model_cfg.device_index = [device_id] if model_cfg.device == "cuda" else [0] + model = WhisperModel(**asdict(model_cfg)) + + inference_cfg = OmegaConf.to_container(self.config.inference, resolve=True) + + output_manifest_file = os.path.join(self.config.dataset.output_dir, f'prediction_{device_id}.json') + + with open(output_manifest_file, 'w', encoding='utf8') as fout: + for entry in tqdm(self.get_entries_for_device(device_id), desc = f"Transcribing ({self.config.model.device.upper()} {device_id})"): + audio_filepath = entry[self.audio_filepath_field] + + if self.language_detection_only: + try: + audio = decode_audio(audio_filepath) + features = model.feature_extractor(audio) + language, language_probability, all_language_probs = model.detect_language(features = features, + vad_filter = self.config.inference.vad_filter, + vad_parameters = self.config.inference.vad_parameters, + language_detection_segments = self.config.inference.language_detection_segments, + language_detection_threshold = self.config.inference.language_detection_threshold) + except Exception: + if self.config.dataset.skip_corrupted: + logger.warning(f"Sample can't be processed: {audio_filepath}. Skipping.") + continue + else: + traceback.print_exc() + exit(1) + + result = dict(language = language, language_probability = language_probability) + else: + try: + if self.config.dataset.offset: + audio = self.get_audio_segment(audio_filepath, entry['offset'], entry['duration']) + else: + audio = audio_filepath + + segments, info = model.transcribe(audio = audio, **inference_cfg) + + except Exception: + if self.config.dataset.skip_corrupted: + logger.warning(f"Sample can't be transcribed: {audio_filepath}. Skipping.") + continue + else: + traceback.print_exc() + exit(1) + + result = serialize(info) + result.pop('all_language_probs', None) + result.pop('transcription_options', None) + result.pop('vad_options', None) + + _segments = [] + for segment in segments: + _segments.append(serialize(segment)) + segments = _segments + + if self.config.dataset.save_timestamps_separately: + audio_filename = os.path.splitext(os.path.basename(audio_filepath))[0] + timestamps_filepaths = self.write_timestamps(audio_filename, segments) + result.update(timestamps_filepaths) + else: + result['segments'] = segments + + pred_text = ' '.join(str(segment['text']) for segment in segments).strip() + result['pred_text'] = pred_text + + entry.update(result) + fout.write(json.dumps(entry, ensure_ascii=False) + "\n") + fout.flush() + + return output_manifest_file + + def process(self): + """ + Main entry point for the processor. + + Prepares directories, distributes transcription tasks across devices, and aggregates results + into the final output manifest file. + """ + self.prepare() + + with Pool(processes=len(self.device_ids)) as pool: + output_rank_manifests = pool.map(self.transcribe, self.device_ids) + + with open(self.output_manifest_file, 'w', encoding='utf8') as output_manifest: + for rank_manifest_filepath in tqdm(output_rank_manifests, desc = "Writing output manifest.."): + with open(rank_manifest_filepath, 'r', encoding='utf8') as rank_manifest: + for line in rank_manifest: + output_manifest.writelines(line) \ No newline at end of file diff --git a/sdp/processors/nemo/asr_inference.py b/sdp/processors/inference/asr/nemo/asr_inference.py similarity index 97% rename from sdp/processors/nemo/asr_inference.py rename to sdp/processors/inference/asr/nemo/asr_inference.py index 4359f320..a826fc54 100644 --- a/sdp/processors/nemo/asr_inference.py +++ b/sdp/processors/inference/asr/nemo/asr_inference.py @@ -49,7 +49,7 @@ def __init__( **kwargs, ): super().__init__(**kwargs) - self.script_path = Path(__file__).parents[1] / "nemo" / "transcribe_speech.py" + self.script_path = Path(__file__).parent / "utils" / "transcribe_speech.py" self.pretrained_model = pretrained_model self.batch_size = batch_size diff --git a/sdp/processors/nemo/transcribe_speech.py b/sdp/processors/inference/asr/nemo/utils/transcribe_speech.py similarity index 100% rename from sdp/processors/nemo/transcribe_speech.py rename to sdp/processors/inference/asr/nemo/utils/transcribe_speech.py diff --git a/sdp/processors/inference/asr/post_processing/whisper_hallucinations.py b/sdp/processors/inference/asr/post_processing/whisper_hallucinations.py new file mode 100644 index 00000000..7362e1a1 --- /dev/null +++ b/sdp/processors/inference/asr/post_processing/whisper_hallucinations.py @@ -0,0 +1,110 @@ +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from sdp.processors.base_processor import BaseParallelProcessor, DataEntry + + +class DetectWhisperHallucinationFeatures(BaseParallelProcessor): + """ + Computes hallucination-related features for ASR model outputs (e.g., Whisper transcripts). + + This processor analyzes the transcript text and flags common hallucination patterns by computing + boolean features such as: + - Repeated or low-diversity n-grams (`hall_repeated_ngrams`) + - Unusually long or disproportionately long words (`hall_long_word`) + - Matches with known hallucinated phrases (`hall_frequent_single_word`) + + It appends these features to each entry in the manifest for downstream filtering or analysis. + + Args: + common_hall_file (str): Path to a file with known hallucinated phrases, one per line. + unique_words_threshold (float): Maximum allowed share of unique words before marking as repeated. Default is 0.4. + long_word_threshold (int): Minimum character length for a word to be considered "long". Default is 25. + long_word_rel_threshold (float): Relative length ratio between the longest and second-longest word. Default is 3. + char_rate_threshold (float): [Unused in current logic, retained for compatibility]. Default is 4. + text_field (str): Key in the data entry that contains the transcript. Default is 'text'. + **kwargs: Additional keyword arguments passed to `BaseParallelProcessor`. + + Returns: + A manifest with additional boolean fields for hallucination detection. + """ + + def __init__( + self, + common_hall_file, + unique_words_threshold=0.4, + long_word_threshold=25, + long_word_rel_threshold=3, + char_rate_threshold=4, + text_field='text', + **kwargs, + ): + super().__init__(**kwargs) + self.unique_words_threshold = unique_words_threshold + self.long_word_threshold = long_word_threshold + self.long_word_rel_threshold = long_word_rel_threshold + self.char_rate_threshold = char_rate_threshold # Currently unused + self.text_field = text_field + + # Load common hallucination phrases into memory + with open(common_hall_file, 'r') as f: + self.common_hall_phrases = [line.strip() for line in f] + + def repeated_ngrams(self, words): + """ + Flags entries with low lexical diversity (i.e., repeated n-grams). + + Returns True if the fraction of unique words is below the threshold. + """ + unique_words_share = len(set(words)) / len(words) + return unique_words_share <= self.unique_words_threshold + + def long_word(self, words): + """ + Detects unusually long words or sharp differences in word lengths. + + Returns True if the longest word is above the absolute threshold or much longer + than the second-longest word. + """ + word_lengths = sorted([len(word) for word in words]) + + if word_lengths[-1] >= self.long_word_threshold: + return True + + if len(words) > 1: + diff = (word_lengths[-1] - word_lengths[-2]) / word_lengths[-2] + return diff >= self.long_word_rel_threshold + + return False + + def frequent_single_word(self, text): + """ + Checks if the cleaned transcript matches any known hallucinated phrase. + """ + cleaned_text = text.strip().replace('.', '').replace('?', '').replace('!', '') + return cleaned_text in self.common_hall_phrases + + def process_dataset_entry(self, data_entry): + """ + Processes a single manifest entry and appends hallucination features. + """ + text = data_entry[self.text_field] + words = text.split() + + # Compute hallucination indicators + data_entry['hall_repeated_ngrams'] = self.repeated_ngrams(words) + data_entry['hall_long_word'] = self.long_word(words) + data_entry['hall_frequent_single_word'] = self.frequent_single_word(text) + + return [DataEntry(data=data_entry)] diff --git a/sdp/processors/huggingface/speech_recognition.py b/sdp/processors/inference/asr/transformers/speech_recognition.py similarity index 100% rename from sdp/processors/huggingface/speech_recognition.py rename to sdp/processors/inference/asr/transformers/speech_recognition.py diff --git a/sdp/processors/inference/llm/post_processing/qwen_cleaning.py b/sdp/processors/inference/llm/post_processing/qwen_cleaning.py new file mode 100644 index 00000000..11fa7a86 --- /dev/null +++ b/sdp/processors/inference/llm/post_processing/qwen_cleaning.py @@ -0,0 +1,131 @@ +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import string + +from sdp.logging import logger +from sdp.processors.base_processor import BaseParallelProcessor, DataEntry +from sdp.utils.metrics_computation import get_cer + + +class CleanQwenGeneration(BaseParallelProcessor): + """ + A processor that filters and post-processes model generations, replacing them with + reference text if they are considered low quality based on character error rate (CER) + and uppercase letter proportion. + + This processor is typically used after running a generation model (e.g., Qwen) to clean + up outputs and ensure alignment with reference transcriptions. + + Args: + cer_threshold (float): Maximum allowable character error rate (CER) between the + normalized generation and reference text. If exceeded, the generation is + replaced by the reference. + upper_case_threshold (float): Threshold for the proportion of uppercase letters in + the generation. If the ratio exceeds this value, the generation is replaced. + generation_field (str): Key in the input manifest for the model-generated text. + text_field (str): Key in the input manifest for the reference (target) text. + **kwargs: Additional arguments passed to the `BaseParallelProcessor`. + + Returns: + A manifest where each entry contains the cleaned generation in the specified + generation field. If a replacement occurred, it is recorded in the metrics. + + Metrics: + - 1 if the generation was replaced with the reference text. + - 0 if the generation was left as-is. + """ + + def __init__( + self, + cer_threshold=10, + upper_case_threshold=0.6, + generation_field='generation', + text_field='text', + **kwargs, + ): + super().__init__(**kwargs) + self.cer_threshold = cer_threshold + self.upper_case_threshold = upper_case_threshold + self.generation_field = generation_field + self.text_field = text_field + + def clean(self, generation): + """Remove template prompts and special tokens from model generation.""" + if "<|endoftext|>" in generation: + generation = generation.split("<|endoftext|>")[0] + + if "Input transcript:" in generation: + generation = generation.replace("Input transcript:", "") + + if "Output:" in generation: + generation = generation.replace("Output:", "") + + if "Output transcript:" in generation: + generation = generation.replace("Output transcript:", "") + + if "\n" in generation: + generation = generation.replace("\n", "") + + return generation + + def maybe_replace_with_text(self, generation, text): + """ + Determine if generation should be replaced with reference text based on + CER and uppercase ratio. + """ + chars = generation.replace(' ', '') + total_chars = len(chars) + + # Replace if generation is empty + if not total_chars: + return text, 1 + + # Replace if excessive capitalization + uppercase_count = sum(1 for char in chars if char.isupper()) + if uppercase_count / total_chars > self.upper_case_threshold: + return text, 1 + + # Normalize both strings for CER comparison + normalized_text = text.lower().translate(str.maketrans('', '', string.punctuation)).strip() + normalized_generation = generation.lower().translate(str.maketrans('', '', string.punctuation)).strip() + + if not normalized_text: + return text, 1 + + cer = get_cer(normalized_text, normalized_generation) + + if cer > self.cer_threshold: + return text, 1 + + return generation, 0 + + def process_dataset_entry(self, data_entry): + """Process a single entry from the manifest: clean and validate generation.""" + text = data_entry[self.text_field] + generation = data_entry[self.generation_field] + + generation = self.clean(generation) + maybe_replaced_generation, replaced = self.maybe_replace_with_text(generation, text) + + data_entry[self.generation_field] = maybe_replaced_generation.strip() + + return [DataEntry(data=data_entry, metrics=replaced)] + + def finalize(self, metrics): + """Log the total number of replaced generations.""" + logger.info( + f"Num of utterances that were replaced by text: {sum(metrics)}" + ) + super().finalize(metrics) diff --git a/sdp/processors/inference/llm/vllm/vllm.py b/sdp/processors/inference/llm/vllm/vllm.py new file mode 100644 index 00000000..08364440 --- /dev/null +++ b/sdp/processors/inference/llm/vllm/vllm.py @@ -0,0 +1,154 @@ +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import yaml +import json +from tqdm import tqdm + +from sdp.processors.base_processor import BaseProcessor + + +class vLLMInference(BaseProcessor): + """ + A processor that performs inference using a vLLM model on entries from an input manifest. + + This class supports three prompt configuration modes: + - a static prompt template (`prompt`) + - a field in each entry containing the prompt (`prompt_field`) + - a YAML file containing the prompt structure (`prompt_file`) + + The prompts are converted into chat-style input using a tokenizer chat template, + passed to the vLLM engine for generation, and the results are written to an output manifest. + + Args: + prompt (str, optional): A fixed prompt used for all entries. + prompt_field (str, optional): The key in each entry that holds the prompt template. + prompt_file (str, optional): Path to a YAML file containing the prompt structure. + generation_field (str): Name of the output field to store generated text. Default is 'generation'. + model (dict): Parameters to initialize the vLLM model. + inference (dict): Sampling parameters passed to vLLM.SamplingParams. + apply_chat_template (dict): Arguments passed to the tokenizer's `apply_chat_template` method. + **kwargs: Passed to the BaseProcessor (includes `input_manifest_file` and `output_manifest_file`). + + Raises: + ValueError: If zero or more than one prompt configuration methods are used simultaneously. + + Returns: + A line-delimited JSON manifest where each entry includes the original fields + plus a field with the generated output. + + .. note:: + For detailed parameter options, refer to the following documentation: + + - model: https://docs.vllm.ai/en/latest/api/vllm/vllm.entrypoints.llm.html#vllm.entrypoints.llm.LLM + - inference: https://docs.vllm.ai/en/v0.6.4/dev/sampling_params.html + - apply_chat_template: https://huggingface.co/docs/transformers/main/en/chat_templating#applychattemplate + + Make sure to install `optree>=0.13.0` and `vllm` before using this processor: + pip install "optree>=0.13.0" vllm + + """ + + def __init__(self, + prompt: str = None, + prompt_field: str = None, + prompt_file: str = None, + generation_field: str = 'generation', + model: dict = {}, + inference: dict = {}, + apply_chat_template: dict = {}, + **kwargs): + + from vllm import SamplingParams + from transformers import AutoTokenizer + + super().__init__(**kwargs) + + self.prompt = prompt + self.prompt_field = prompt_field + self.generation_field = generation_field + + # Ensure that exactly one prompt method is used + prompt_args_counter = sum([prompt is not None, prompt_field is not None, prompt_file is not None]) + if prompt_args_counter < 1: + raise ValueError(f'One of `prompt`, `prompt_field` or `prompt_file` should be provided.') + elif prompt_args_counter > 1: + err = [] + if prompt: + err.append(f'`prompt` ({prompt})') + if prompt_field: + err.append(f'`prompt_field` ({prompt_field})') + if prompt_file: + err.append(f'`prompt_file` ({prompt_file})') + raise ValueError(f'Found more than one prompt values: {", ".join(err)}.') + + if prompt_file: + self.prompt = self._read_prompt_file(prompt_file) + + self.model_params = model + self.sampling_params = SamplingParams(**inference) + self.chat_template_params = apply_chat_template + + self.tokenizer = AutoTokenizer.from_pretrained(self.model_params['model']) + + def _read_prompt_file(self, prompt_filepath): + """Read a YAML file with a chat-style prompt template.""" + with open(prompt_filepath, 'r') as prompt: + return yaml.safe_load(prompt) + + def get_entry_prompt(self, data_entry): + """Format the prompt for a single data entry using the chat template.""" + entry_chat = [] + prompt = self.prompt + if self.prompt_field: + prompt = data_entry[self.prompt_field] + + for role in prompt: + entry_chat.append(dict( + role=role, + content=prompt[role].format(**data_entry) + )) + + entry_prompt = self.tokenizer.apply_chat_template( + entry_chat, + **self.chat_template_params + ) + + return entry_prompt + + def process(self): + """Main processing function: reads entries, builds prompts, runs generation, writes results.""" + from vllm import LLM + + entries = [] + entry_prompts = [] + + # Read entries and generate prompts + with open(self.input_manifest_file, 'r', encoding='utf8') as fin: + for line in tqdm(fin, desc = "Building prompts: "): + data_entry = json.loads(line) + entries.append(data_entry) + entry_prompt = self.get_entry_prompt(data_entry) + entry_prompts.append(entry_prompt) + + # Run vLLM inference + llm = LLM(**self.model_params) + outputs = llm.generate(entry_prompts, self.sampling_params) + + # Write results to output manifest + with open(self.output_manifest_file, 'w', encoding='utf8') as fout: + for data_entry, output in tqdm(zip(entries, outputs), desc="Writing outputs: "): + data_entry[self.generation_field] = output.outputs[0].text + line = json.dumps(data_entry) + fout.writelines(f'{line}\n') diff --git a/sdp/processors/inference/nlp/fasttext/fasttext.py b/sdp/processors/inference/nlp/fasttext/fasttext.py new file mode 100644 index 00000000..7b0663e0 --- /dev/null +++ b/sdp/processors/inference/nlp/fasttext/fasttext.py @@ -0,0 +1,118 @@ +# Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import requests +import tempfile +import wget + +from sdp.logging import logger +from sdp.processors.base_processor import BaseParallelProcessor, DataEntry + + +class FastTextLangIdClassifier(BaseParallelProcessor): + """ + This processor supports language identification using pretrained FastText models. + It classifies text and adds the predicted label and probability to the dataset entry. + If needed, it downloads the model, loads it into memory, and performs prediction on the + specified input text field. + + Args: + model_name_or_path (str): Path to a FastText model file or the name of a supported remote model ('lid.176.bin' or 'lid.176.ftz'). + text_field (str): The name of the field in the dataset entry that contains the input text for classification. + output_field (str): The name of the field to store the predicted label. Defaults to "label". + cache_dir (str, optional): Directory to store the downloaded model file. If not provided, a temporary directory is used. + **kwargs: Additional keyword arguments passed to `BaseParallelProcessor`. + + Returns: + A manifest where each entry contains the original data fields plus: + - ``: The predicted label (e.g., language code for `lid.176.bin`). + - `_prob`: The probability of the prediction. + + .. note:: + Make sure to install `fasttext` before using this processor: + pip install fasttext + + """ + + SUPPROTED_MODELS_URLS = { + 'lid.176.bin' : 'https://dl.fbaipublicfiles.com/fasttext/supervised-models/lid.176.bin', + 'lid.176.ftz' : 'https://dl.fbaipublicfiles.com/fasttext/supervised-models/lid.176.ftz' + } + + def __init__( + self, + model_name_or_path: str, + text_field: str, + output_field: str = "label", + cache_dir: str = None, + **kwargs + ): + super().__init__(**kwargs) + self.model_name_or_path = model_name_or_path + self.text_field = text_field + self.output_field = output_field + self.cache_dir = cache_dir + self._model = None + + def _download_model(self): + """Downloads the FastText model from a predefined URL and stores it in the cache directory.""" + model_url = self.SUPPROTED_MODELS_URLS[self.model_name_or_path] + logger.info(f'Downloading {self.model_name_or_path}..') + response = requests.get(model_url) + + if response.status_code != 200: + raise requests.exceptions.RequestException( + f"Failed to download model file. Status code: {response.status_code}" + ) + + if self.cache_dir is None: + self.cache_dir = tempfile.mkdtemp() + os.makedirs(self.cache_dir, exist_ok=True) + + self.model_name_or_path = wget.download(model_url, out=self.cache_dir) + logger.info(f'Model `{self.model_name_or_path}` has been downloaded to {self.cache_dir}.') + + def _load_model(self): + """Lazily loads the FastText model into memory.""" + import fasttext + + if self._model is None: + self._model = fasttext.load_model(self.model_name_or_path) + + def prepare(self): + """ + Prepares the model for classification: + - Checks if the model file exists locally. + - Downloads the model if only the name is given and it's known. + - Raises ValueError if the path or model name is invalid. + """ + if not os.path.exists(self.model_name_or_path): + if os.path.exists(os.path.join(self.cache_dir, self.model_name_or_path)): + self.model_name_or_path = os.path.join(self.cache_dir, self.model_name_or_path) + elif self.model_name_or_path in self.SUPPROTED_MODELS_URLS: + self._download_model() + else: + raise ValueError(f'Current model is not supported or filepath is invalid: {self.model_name_or_path}.') + + def process_dataset_entry(self, data_entry: dict): + """Applies the classifier to a single dataset entry.""" + + self._load_model() + text = data_entry[self.text_field].strip().replace("\n", " ") + label, prob = self._model.predict(text) + data_entry[self.output_field] = label[0].replace('__label__', '') + data_entry[f"{self.output_field}_prob"] = prob[0] + + return [DataEntry(data=data_entry)] diff --git a/sdp/processors/nemo/pc_inference.py b/sdp/processors/inference/nlp/nemo/pc_inference.py similarity index 100% rename from sdp/processors/nemo/pc_inference.py rename to sdp/processors/inference/nlp/nemo/pc_inference.py diff --git a/sdp/processors/inference/quality_estimation/pymarian.py b/sdp/processors/inference/quality_estimation/pymarian.py new file mode 100644 index 00000000..0e15eaad --- /dev/null +++ b/sdp/processors/inference/quality_estimation/pymarian.py @@ -0,0 +1,216 @@ +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import json +from tqdm import tqdm +import termplotlib as tpl +import numpy as np + +from sdp.logging import logger +from sdp.processors.base_processor import BaseParallelProcessor + +class CometoidWMTQualityEstimation(BaseParallelProcessor): + """ + A processor for estimating translation quality using pretrained COMET-like models + based on MarianNMT and the pymarian Evaluator. + + This processor evaluates the quality of source-target text pairs (bitext) using + COMETOID-style quality estimation and appends the resulting score to each dataset entry. + + Args: + source_text_field (str): The key in the data entry containing the source (original) text. + target_text_field (str): The key in the data entry containing the target (translated) text. + model_name_or_path (str): Hugging Face model name or path to local model checkpoint. + vocab_path (str, optional): Path to the vocabulary file. If None and model is from HF, it will be downloaded. + save_model_to (str, optional): Directory to download and cache the model and vocab. + mini_batch (int): Mini-batch size for evaluation. + maxi_batch (int): Maxi-batch size for evaluation. + output_field (str): The name of the field where the quality score will be saved in the output manifest. + device_type (str): Device type to use: 'cpu' or 'gpu'. + num_devices (int): Number of CPU threads or GPU devices to use. Use -1 to use all available. + chunksize (int): Number of lines to process in each chunk. + + Returns: + A manifest file where each entry has an added key (`output_field`) with the computed score. + + .. note:: + This processor uses MarianNMT models fine-tuned for quality estimation. See https://marian-nmt.github.io/. + + Make sure to install `pymarian` before using this processor: + pip install pymarian + """ + + # Mapping of supported model aliases to Hugging Face repo paths + MODEL_NAME_TO_HF_PATH = { + "cometoid-wmt23": "marian-nmt/cometoid22-wmt23", + "cometoid-wmt23-mqm": "marian-nmt/cometoid22-wmt23", + } + + # Marian evaluation arguments depending on device + MARIAN_GPU_ARGS = "-w 8000 -d {device_indicies}" + MARIAN_CPU_ARGS = "-w 2000 --cpu-threads {num_threads}" + + def __init__(self, + source_text_field: str, + target_text_field: str, + model_name_or_path: str, + vocab_path: str = None, + save_model_to: str = None, + mini_batch: int = 16, + maxi_batch: int = 96, + output_field: str = 'cometoid_score', + device_type: str = 'cpu', + num_devices: int = -1, + chunksize = 5000, + **kwargs, + ): + super().__init__(max_workers = num_devices, chunksize = chunksize, in_memory_chunksize = chunksize, **kwargs) + self.source_text_field = source_text_field + self.target_text_field = target_text_field + self.model_name_or_path = model_name_or_path + self.vocab_path = vocab_path + self.save_model_to = save_model_to + self.device_type = device_type + self.mini_batch = mini_batch + self.maxi_batch = maxi_batch + self.output_field = output_field + self.model = None + + def load_model(self): + from pymarian import Evaluator + from huggingface_hub import hf_hub_download + + """ + Load the model and vocabulary from Hugging Face if necessary. + Assemble command-line arguments for launching pymarian Evaluator. + Depending on the device (CPU/GPU), configure parallelism parameters. + """ + repo_id = None + if self.model_name_or_path in self.MODEL_NAME_TO_HF_PATH: + repo_id = self.MODEL_NAME_TO_HF_PATH[self.model_name_or_path] + self.model_name_or_path = hf_hub_download(repo_id, filename="checkpoints/marian.model.bin", local_dir = self.save_model_to) + + if not os.path.exists(self.model_name_or_path): + raise ValueError(f'`model_name_or_path`: model name is not valid or model path does not exist ({self.model_name_or_path}).') + + if not self.vocab_path and repo_id is not None: + self.vocab_path = hf_hub_download(repo_id=repo_id, filename="vocab.spm", local_dir = self.save_model_to) + + if not os.path.exists(self.vocab_path): + raise FileNotFoundError(f'`vocab_path`: path does not exist ({self.vocab_path}).') + + marian_args = f"-m {self.model_name_or_path} -v {self.vocab_path} {self.vocab_path} --like comet-qe" + + if self.device_type == "cpu": + max_available_cpus = os.cpu_count() + if self.max_workers == -1 or self.max_workers > max_available_cpus: + self.max_workers = max_available_cpus + + cpu_args = self.MARIAN_CPU_ARGS.format(num_threads = self.max_workers) + marian_args += f' {cpu_args}' + else: + try: + import torch + if torch.cuda.is_available(): + max_available_gpus = torch.cuda.device_count() + if self.max_workers == -1 or self.max_workers > max_available_gpus: + self.max_workers = max_available_cpus + except Exception: + pass + + device_indicies = ' '.join([str(i) for i in range(self.max_workers)]) + gpu_args = self.MARIAN_GPU_ARGS.format(device_indicies = device_indicies) + marian_args += f' {gpu_args}' + + marian_args += f' --mini-batch {self.mini_batch} --maxi-batch {self.maxi_batch}' + + self.model = Evaluator(marian_args) + + def process_dataset_entry(self): + pass + + def process(self): + """ + Process the entire manifest in chunks. + For each pair of texts (source–target), compute the translation quality score. + Save the resulting scores in output_manifest_file. + """ + self.load_model() + os.makedirs(os.path.dirname(self.output_manifest_file), exist_ok=True) + metrics = [] + + with open(self.output_manifest_file, "wt", encoding="utf8") as fout: + for manifest_chunk in self._chunk_manifest(): + entries = [] + bitext_pairs = [] + for data_entry in manifest_chunk: + src = str(data_entry[self.source_text_field]).replace('\t', ' ') + tgt = str(data_entry[self.target_text_field]).replace('\t', ' ') + bitext_pairs.append(f'{src}\t{tgt}') + entries.append(data_entry) + + scores = self.model.evaluate(bitext_pairs) + for entry, score in tqdm(zip(entries, scores)): + metrics.append(score) + entry[self.output_field] = score + json.dump(entry, fout, ensure_ascii=False) + self.number_of_entries += 1 + fout.write("\n") + + self.finalize(metrics) + + def finalize(self, metrics): + """ + Print statistics about the quality scores: histogram, min, max, mean, median. + Use termplotlib to render the histogram directly in the terminal. + """ + logger.info("Total number of entries after processing: %d", self.number_of_entries) + logger.info("Histogram of scores:") + + bins = np.arange(0, 1.1, 0.1) + hist, bin_edges = np.histogram(metrics, bins=bins) + + labels = [] + for i in range(len(bin_edges) - 1): + left = f"{bin_edges[i]:.1f}" + right = f"{bin_edges[i+1]:.1f}" + if i < len(bin_edges) - 2: + labels.append(f"[{left}–{right})") + else: + labels.append(f"[{left}–{right}]") + + fig = tpl.figure() + fig.barh(hist, labels) + fig.show() + + logger.info(f"Min score: {np.min(metrics):.4f}") + logger.info(f"Max score: {np.max(metrics):.4f}") + logger.info(f"Mean score: {np.mean(metrics):.4f}") + logger.info(f"Median score: {np.median(metrics):.4f}") + + + + + + + + + + + + + + + diff --git a/sdp/processors/manage_files/convert_audio.py b/sdp/processors/manage_files/convert_audio.py new file mode 100644 index 00000000..7cdc2e73 --- /dev/null +++ b/sdp/processors/manage_files/convert_audio.py @@ -0,0 +1,170 @@ +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +from typing import Optional +from sox import Transformer + +from sdp.logging import logger +from sdp.processors.base_processor import BaseParallelProcessor, DataEntry + +from sdp.utils.common import ffmpeg_convert + + +class FfmpegConvert(BaseParallelProcessor): + """ + Processor for converting video or audio files to audio using FFmpeg and updating the dataset with the path to the resampled audio. + If ``id_key`` is not None, the output file path will be ``/.wav``. + If ``id_key`` is None, the output file path will be ``/.wav``. + + .. note:: ``id_key`` can be used to create subdirectories inside ``resampled_audio_dir`` (by using forward slashes ``/``). + e.g. if ``id_key`` takes the form ``dir_name1/dir_name2/filename``, the output file path will be + + ``/dir_name1/dirname2/filename.wav``. + + Args: + converted_audio_dir (str): The directory to store the resampled audio files. + input_file_key (str): The field in the dataset representing the path to the input video or audio files. + output_file_key (str): The field in the dataset representing the path to the resampled audio files with ``output_format``. If ``id_key`` is None, the output file path will be ``/.wav``. + id_key (str): (Optional) The field in the dataset representing the unique ID or identifier for each entry. If ``id_key`` is not None, the output file path will be ``/.wav``. Defaults to None. + output_format (str): (Optional) Format of the output audio files. Defaults to `wav`. + target_samplerate (int): (Optional) The target sampling rate for the resampled audio. Defaults to 16000. + target_nchannels (int): (Optional) The target number of channels for the resampled audio. Defaults to 1. + **kwargs: Additional keyword arguments to be passed to the base class `BaseParallelProcessor`. + + """ + + def __init__( + self, + converted_audio_dir: str, + input_file_key: str, + output_file_key: str, + id_key: str = None, + output_format: str = "wav", + base_dir: str = None, + target_samplerate: int = 16000, + target_nchannels: int = 1, + **kwargs, + ): + super().__init__(**kwargs) + self.converted_audio_dir = converted_audio_dir + self.input_file_key = input_file_key + self.output_file_key = output_file_key + self.output_format = output_format + self.id_key = id_key + self.base_dir = base_dir + self.target_samplerate = target_samplerate + self.target_nchannels = target_nchannels + + def prepare(self): + assert self.output_format == "wav", "Currently only wav format is supported" + os.makedirs(self.converted_audio_dir, exist_ok=True) + + def process_dataset_entry(self, data_entry): + input_file = data_entry[self.input_file_key] + if self.id_key: + key = data_entry[self.id_key] + os.makedirs(os.path.join(self.converted_audio_dir, *key.split("/")[:-1]), exist_ok=True) + else: + key = os.path.splitext(input_file)[0].split("/")[-1] + + if self.base_dir: + new_dir = os.path.dirname(os.path.relpath(input_file, self.base_dir)) + os.makedirs(os.path.join(self.converted_audio_dir, new_dir), exist_ok=True) + + key = os.path.join(new_dir, key) + + audio_file = os.path.join(self.converted_audio_dir, key) + "." + self.output_format + + if not os.path.isfile(audio_file): + ffmpeg_convert(input_file, audio_file, self.target_samplerate, self.target_nchannels) + + data_entry[self.output_file_key] = audio_file + return [DataEntry(data=data_entry)] + + +class SoxConvert(BaseParallelProcessor): + """Processor for Sox to convert audio files to specified format. + + Args: + output_manifest_file (str): Path to the output manifest file. + input_audio_file_key (str): Key in the manifest file that contains the path to the input audio file. + output_audio_file_key (str): Key in the manifest file that contains the path to the output audio file. + converted_audio_dir (str): Path to the directory where the converted audio files will be stored. + output_format (str): Format of the output audio file. + rate (int): Sample rate of the output audio file. + channels (int): Number of channels of the output audio file. + workspace_dir (str, Optional): Path to the workspace directory. Defaults to None. + """ + + def __init__( + self, + converted_audio_dir: str, + input_audio_file_key: str = "audio_filepath", + output_audio_file_key: str = "audio_filepath", + output_format: str = "wav", + rate: int = 16000, + channels: int = 1, + workspace_dir: Optional[str] = None, + **kwargs, + ): + # Extract workspace_dir from kwargs to avoid passing it to BaseProcessor + if "workspace_dir" in kwargs: + workspace_dir = kwargs.pop("workspace_dir") + + super().__init__(**kwargs) + self.input_audio_file_key = input_audio_file_key + self.output_audio_file_key = output_audio_file_key + self.converted_audio_dir = converted_audio_dir + self.output_format = output_format + self.workspace_dir = workspace_dir + + # Store the new parameters for later use: + self.rate = rate + self.channels = channels + + def prepare(self): + # Debug print for workspace_dir + logger.info(f"SoxConvert workspace_dir: {self.workspace_dir}") + os.makedirs(self.converted_audio_dir, exist_ok=True) + + def process_dataset_entry(self, data_entry): + audio_path = data_entry[self.input_audio_file_key] + + # If workspace_dir is provided, join it with audio_path to get absolute path + if self.workspace_dir is not None: + full_audio_path = os.path.join(self.workspace_dir, audio_path) + else: + full_audio_path = audio_path + + # Debug print first file path + if not hasattr(self, '_debug_printed'): + logger.info(f"First audio_path from manifest: {audio_path}") + logger.info(f"First full_audio_path: {full_audio_path}") + logger.info(f"Path exists: {os.path.exists(full_audio_path)}") + self._debug_printed = True + + key = os.path.splitext(audio_path)[0].split("/")[-1] + converted_file = os.path.join(self.converted_audio_dir, key) + f".{self.output_format}" + + if not os.path.isfile(converted_file): + transformer = Transformer() + + transformer.rate(self.rate) + transformer.channels(self.channels) + + transformer.build(full_audio_path, converted_file) + + data_entry[self.output_audio_file_key] = converted_file + return [DataEntry(data=data_entry)] diff --git a/sdp/processors/manage_files/convert_to_tarred_audio_dataset.py b/sdp/processors/manage_files/convert_to_tarred_audio_dataset.py new file mode 100644 index 00000000..93f4a970 --- /dev/null +++ b/sdp/processors/manage_files/convert_to_tarred_audio_dataset.py @@ -0,0 +1,160 @@ +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import json +from dataclasses import dataclass +from typing import Optional +from copy import deepcopy +from tqdm import tqdm +import shutil + +from sdp.processors.base_processor import BaseProcessor +from sdp.processors.manage_files.utils.convert_to_tarred_audio_dataset import create_tar_datasets + + +@dataclass +class ConvertToTarredAudioDatasetConfig: + """ + Configuration class for ConvertToTarredAudioDataset. + + Attributes: + max_duration (float): Maximum allowed duration for audio samples. + min_duration (Optional[float]): Minimum allowed duration for audio samples. + concat_manifest_paths (Optional[str]): Path to a manifest file containing multiple manifest paths to concatenate. + target_dir (Optional[str]): Output directory to save tarred dataset. + metadata_path (Optional[str]): Path to write metadata about the tarred dataset. + num_shards (int): Number of shards to create. If -1, it will be determined automatically. + shuffle (bool): Whether to shuffle the input manifest before processing. + keep_files_together (bool): If True, all segments from the same source file are kept in the same shard. + sort_in_shards (bool): If True, samples inside each shard will be sorted by duration. + buckets_num (int): Number of duration-based buckets to split data into. + dynamic_buckets_num (int): Number of dynamic buckets for load balancing. + shuffle_seed (Optional[int]): Random seed used for shuffling. + write_metadata (bool): Whether to write metadata JSON files during processing. + no_shard_manifests (bool): If True, disables writing per-shard manifest files. + force_codec (Optional[str]): Audio codec to use when re-encoding audio files. + workers (int): Number of worker processes for parallel audio re-encoding. + slice_with_offset (bool): If True, audio slices will use offset and duration fields. + only_manifests (bool): If True, only manifests will be generated without audio re-encoding. + """ + max_duration: float + min_duration: Optional[float] = None + concat_manifest_paths: Optional[str] = None + target_dir: Optional[str] = None + metadata_path: Optional[str] = None + num_shards: int = -1 + shuffle: bool = False + keep_files_together: bool = False + sort_in_shards: bool = False + buckets_num: int = 1 + dynamic_buckets_num: int = 30 + shuffle_seed: Optional[int] = None + write_metadata: bool = False + no_shard_manifests: bool = False + force_codec: Optional[str] = None + workers: int = 1 + slice_with_offset: bool = False + only_manifests: bool = False + + +class ConvertToTarredAudioDataset(BaseProcessor): + """ + A processor for converting audio manifests into tarred audio datasets. + + This processor optionally splits data into duration-based buckets, and calls the + `create_tar_datasets` utility to convert and shard audio data into tar files, + with accompanying manifest files. + + Args: + output_manifest_file (str): Path to the final output manifest. + input_manifest_file (str): Path to the input manifest to be tarred. + **cfg_kwargs: Additional keyword arguments passed to the configuration dataclass. + + Returns: + Writes a tarred and sharded audio dataset to disk. + + - The dataset consists of multiple `.tar` archives with audio files. + - A final manifest (JSON lines format) is written to ``output_manifest_file``, + referencing each sample, its path inside the tar, and other metadata. + - If ``buckets_num > 1``, each sample will include an additional ``bucket_id`` field. + + .. note:: + If `buckets_num > 1`, the input manifest is split into multiple duration buckets, + and each bucket is processed independently. A `bucket_id` is added to each sample. + + You may need to install the extra dependencies of Lhotse and NeMo for this processor to work correctly: + ``pip install lhotse "nemo-toolkit[common]"`` + + """ + + def __init__( + self, + output_manifest_file: str, + input_manifest_file: str = None, + **cfg_kwargs, + ): + super().__init__( + input_manifest_file=input_manifest_file, + output_manifest_file=output_manifest_file + ) + self.cfg = ConvertToTarredAudioDatasetConfig(**cfg_kwargs) + + def process(self): + # If bucketing is enabled, divide the data based on duration ranges. + if self.cfg.buckets_num > 1: + with open(self.output_manifest_file, 'w', encoding='utf8') as fout: + bucket_length = (self.cfg.max_duration - self.cfg.min_duration) / float(self.cfg.buckets_num) + + for i_bucket in range(self.cfg.buckets_num): + # Create a config for the current bucket + bucket_config = deepcopy(self.cfg) + bucket_config.min_duration = self.cfg.min_duration + i_bucket * bucket_length + bucket_config.max_duration = bucket_config.min_duration + bucket_length + if i_bucket == self.cfg.buckets_num - 1: + # Ensure final bucket includes edge cases + bucket_config.max_duration += 1e-5 + + bucket_config.target_dir = os.path.join(self.cfg.target_dir, f"bucket{i_bucket+1}") + + print(f"Creating bucket {i_bucket+1} with min_duration={bucket_config.min_duration} and max_duration={bucket_config.max_duration} ...") + print(f"Results are being saved at: {bucket_config.target_dir}.") + + # Create tarred dataset for the current bucket + create_tar_datasets( + manifest_path=self.input_manifest_file, + **vars(bucket_config) + ) + + # Read and modify the output manifest from this bucket + bucket_manifest_path = os.path.join(bucket_config.target_dir, 'tarred_audio_manifest.json') + with open(bucket_manifest_path, 'r', encoding='utf8') as bin_f: + for line in tqdm(bin_f, desc="Writing output manifest.."): + entry = json.loads(line) + entry['bucket_id'] = i_bucket + line = json.dumps(entry) + fout.writelines(f'{line}\n') + + print(f"Bucket {i_bucket+1} is created.") + + else: + # No bucketing — create single tarred dataset + create_tar_datasets( + manifest_path=self.input_manifest_file, + **vars(self.cfg) + ) + + # Copy the generated manifest to the target location + tarred_audio_manifest = os.path.join(self.cfg.target_dir, 'tarred_audio_manifest.json') + shutil.copy(tarred_audio_manifest, self.output_manifest_file) \ No newline at end of file diff --git a/sdp/processors/manage_files/extract.py b/sdp/processors/manage_files/extract.py new file mode 100644 index 00000000..83638aba --- /dev/null +++ b/sdp/processors/manage_files/extract.py @@ -0,0 +1,118 @@ +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import tarfile +import os +from pathlib import Path + +from sdp.logging import logger +from sdp.processors.base_processor import DataEntry, BaseParallelProcessor + + +class ExtractTar(BaseParallelProcessor): + """ + A processor that extracts `.tar` archives for each entry in a dataset. + + This processor reads a filepath to a tar archive from a specific field in the dataset entry, + extracts the contents into a specified directory, and optionally appends the extracted file paths + or the extraction directory to the entry under a new field. + + Args: + field_to_tar_filepath (str): The field in the input entry that contains the path to the `.tar` file. + extraction_dir (str): The base directory where extracted files should be placed. + remove_source_tar (bool): If True, deletes the original `.tar` file after successful extraction. + skip_invalid_filepaths (bool): If True, logs and skips invalid paths instead of raising exceptions. + filepath_prefix_field (str): Optional field in the entry used as a subdirectory prefix under `extraction_dir`. + output_filepath_field (str): Field name where the output (path or list of paths) will be stored. + get_extracted_filepaths (bool): If True, collects and returns a list of all extracted file paths. + + Returns: + A manifest where each entry is updated with the path to the extracted files or directory. + """ + + def __init__( + self, + field_to_tar_filepath: str, + extraction_dir: str, + remove_source_tar: bool = False, + skip_invalid_filepaths: bool = False, + filepath_prefix_field: str = None, + output_filepath_field: str = 'extracted', + get_extracted_filepaths: bool = False, + **kwargs + ): + super().__init__(**kwargs) + self.field_to_tar_filepath = field_to_tar_filepath + self.extraction_dir = extraction_dir + self.remove_source_tar = remove_source_tar + self.skip_invalid_filepaths = skip_invalid_filepaths + self.filepath_prefix_field = filepath_prefix_field + self.output_filepath_field = output_filepath_field + self.get_extracted_filepaths = get_extracted_filepaths + + def process_dataset_entry(self, data_entry): + # Read the tar file path from the specified field + tar_filepath = data_entry[self.field_to_tar_filepath] + + # Handle missing or invalid tar file path + if not isinstance(tar_filepath, str) or not os.path.exists(tar_filepath): + if self.skip_invalid_filepaths: + logger.info(f"Invalid filepath {tar_filepath}. Skipping..") + output_filepath = None + else: + raise ValueError(f"Invalid filepath {tar_filepath}.") + else: + # Determine output path using optional prefix and tar filename + output_filepath_prefix = ( + data_entry[self.filepath_prefix_field] + if self.filepath_prefix_field and data_entry.get(self.filepath_prefix_field) + else '' + ) + output_filepath = os.path.join( + self.extraction_dir, + output_filepath_prefix, + os.path.basename(tar_filepath).split('.')[0] + ) + os.makedirs(output_filepath, exist_ok=True) + + # Extract tar archive into target directory + try: + with tarfile.open(tar_filepath, 'r') as tar: + tar.extractall(path=output_filepath) + except Exception as e: + if self.skip_invalid_filepaths: + logger.info(f"Error extracting {tar_filepath}: {e}. Skipping..") + output_filepath = None + else: + raise ValueError(f"Error extracting {tar_filepath}: {e}") + + # Gather list of all extracted files if requested + extracted_filepaths = [] + if output_filepath is not None and self.get_extracted_filepaths: + extraction_folder_path = Path(output_filepath) + extracted_filepaths = [ + str(file) for file in extraction_folder_path.rglob("*") if file.is_file() + ] + + # Optionally remove the original tar archive after extraction + if self.remove_source_tar: + os.remove(tar_filepath) + + # Write the extraction result into the entry (either path or file list) + if self.get_extracted_filepaths: + data_entry[self.output_filepath_field] = extracted_filepaths + else: + data_entry[self.output_filepath_field] = output_filepath + + return [DataEntry(data=data_entry)] diff --git a/sdp/processors/manage_files/remove.py b/sdp/processors/manage_files/remove.py new file mode 100644 index 00000000..0befa50a --- /dev/null +++ b/sdp/processors/manage_files/remove.py @@ -0,0 +1,86 @@ +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import shutil + +from sdp.logging import logger +from sdp.processors.base_processor import DataEntry, BaseParallelProcessor + + +class RemoveFiles(BaseParallelProcessor): + """ + A processor that removes files or directories from the filesystem based on a filepath + specified in the input data entry. + + This processor is typically used for cleanup tasks after processing files. + + Args: + filepath_field (str): The key in the data entry that holds the path to the file or directory to remove. + + drop_filepath_field (bool): Whether to remove the filepath field from the resulting data entry. Defaults to True. + + **kwargs: Additional arguments passed to the BaseParallelProcessor. + + Returns: + A manifest where each entry is the same as the input, optionally without the filepath field, + and with the file or directory at the specified path removed from disk. + + Example entry before processing:: + + { + "id": "abc123", + "path_to_remove": "/tmp/some_file.wav" + } + + Example entry after processing (if `drop_filepath_field=True`):: + + { + "id": "abc123" + } + """ + + def __init__(self, + filepath_field: str, + drop_filepath_field: bool = True, + **kwargs): + + super().__init__(**kwargs) + self.filepath_field = filepath_field + self.drop_filepath_field = drop_filepath_field + + def process_dataset_entry(self, data_entry): + """ + Remove the file or directory specified in the given field of the data entry. + + Args: + data_entry (dict): A single input sample from the dataset manifest. + + Returns: + List[DataEntry]: A single-element list containing the updated entry. + """ + filepath = data_entry[self.filepath_field] + + # Remove the target path from the filesystem + if os.path.isdir(filepath): + shutil.rmtree(filepath) # Recursively delete directory + else: + os.remove(filepath) # Delete a single file + + # Optionally remove the filepath field from the data entry + if self.drop_filepath_field: + data_entry.pop(self.filepath_field) + + # Wrap and return the modified entry + return [DataEntry(data=data_entry)] diff --git a/sdp/processors/manage_files/utils/convert_to_tarred_audio_dataset.py b/sdp/processors/manage_files/utils/convert_to_tarred_audio_dataset.py new file mode 100644 index 00000000..c06462a9 --- /dev/null +++ b/sdp/processors/manage_files/utils/convert_to_tarred_audio_dataset.py @@ -0,0 +1,1021 @@ +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +# This script converts an existing audio dataset with a manifest to +# a tarred and sharded audio dataset that can be read by the +# TarredAudioToTextDataLayer. + +# Please make sure your audio_filepath DOES NOT CONTAIN '-sub'! +# Because we will use it to handle files which have duplicate filenames but with different offsets +# (see function create_shard for details) + + +# Bucketing can help to improve the training speed. You may use --buckets_num to specify the number of buckets. +# It creates multiple tarred datasets, one per bucket, based on the audio durations. +# The range of [min_duration, max_duration) is split into equal sized buckets. +# Recommend to use --sort_in_shards to speedup the training by reducing the paddings in the batches +# More info on how to use bucketing feature: https://docs.nvidia.com/deeplearning/nemo/user-guide/docs/en/main/asr/datasets.html + +# If valid NVIDIA DALI version is installed, will also generate the corresponding DALI index files that need to be +# supplied to the config in order to utilize webdataset for efficient large dataset handling. +# NOTE: DALI + Webdataset is NOT compatible with Bucketing support ! + +# Usage: +1) Creating a new tarfile dataset + +python convert_to_tarred_audio_dataset.py \ + --manifest_path= \ + --target_dir= \ + --num_shards= \ + --max_duration= \ + --min_duration= \ + --shuffle --shuffle_seed=1 \ + --sort_in_shards \ + --force_codec=flac \ + --workers=-1 + + +2) Concatenating more tarfiles to a pre-existing tarred dataset + +python convert_to_tarred_audio_dataset.py \ + --manifest_path= \ + --metadata_path= \ + --target_dir= \ + --max_duration= \ + --min_duration= \ + --shuffle --shuffle_seed=1 \ + --sort_in_shards \ + --workers=-1 \ + --concat_manifest_paths + + +3) Writing an empty metadata file + +python convert_to_tarred_audio_dataset.py \ + --target_dir= \ + # any other optional argument + --num_shards=8 \ + --max_duration=16.7 \ + --min_duration=0.01 \ + --shuffle \ + --workers=-1 \ + --sort_in_shards \ + --shuffle_seed=1 \ + --write_metadata + +""" +import argparse +import copy +import json +import os +import random +import tarfile +from collections import defaultdict +from dataclasses import dataclass, field +from datetime import datetime +from io import BytesIO +from typing import Any, List, Optional + +import numpy as np +import soundfile as sf +from joblib import Parallel, delayed +from omegaconf import DictConfig, OmegaConf, open_dict +from tabulate import tabulate +from tqdm import tqdm + +try: + import create_dali_tarred_dataset_index as dali_index + + DALI_INDEX_SCRIPT_AVAILABLE = True +except (ImportError, ModuleNotFoundError, FileNotFoundError): + DALI_INDEX_SCRIPT_AVAILABLE = False + + +@dataclass +class ASRTarredDatasetConfig: + num_shards: int = -1 + shuffle: bool = False + max_duration: Optional[float] = None + min_duration: Optional[float] = None + shuffle_seed: Optional[int] = None + sort_in_shards: bool = True + slice_with_offset: bool = True + shard_manifests: bool = True + keep_files_together: bool = False + force_codec: Optional[str] = None + use_lhotse: bool = False + use_bucketing: bool = False + num_buckets: Optional[int] = None + bucket_duration_bins: Optional[list[float]] = None + + +@dataclass +class ASRTarredDatasetMetadata: + created_datetime: Optional[str] = None + version: int = 0 + num_samples_per_shard: Optional[int] = None + is_concatenated_manifest: bool = False + + dataset_config: Optional[ASRTarredDatasetConfig] = field(default_factory=lambda: ASRTarredDatasetConfig()) + history: Optional[List[Any]] = field(default_factory=lambda: []) + + def __post_init__(self): + self.created_datetime = self.get_current_datetime() + + def get_current_datetime(self): + return datetime.now().strftime("%m-%d-%Y %H-%M-%S") + + @classmethod + def from_config(cls, config: DictConfig): + obj = cls() + obj.__dict__.update(**config) + return obj + + @classmethod + def from_file(cls, filepath: str): + config = OmegaConf.load(filepath) + return ASRTarredDatasetMetadata.from_config(config=config) + + +class ASRTarredDatasetBuilder: + """ + Helper class that constructs a tarred dataset from scratch, or concatenates tarred datasets + together and constructs manifests for them. + """ + + def __init__(self): + self.config = None + + def configure(self, config: ASRTarredDatasetConfig): + """ + Sets the config generated from command line overrides. + + Args: + config: ASRTarredDatasetConfig dataclass object. + """ + self.config = config # type: ASRTarredDatasetConfig + + if self.config.num_shards < 0: + raise ValueError("`num_shards` must be > 0. Please fill in the metadata information correctly.") + + def create_new_dataset( + self, + manifest_path: str, + target_dir: str = "./tarred/", + num_workers: int = 0, + buckets_num: int = 1, + dynamic_buckets_num: int = 30, + only_manifests: bool = False, + dry_run: bool = False, + ): + """ + Creates a new tarred dataset from a given manifest file. + + Args: + manifest_path (str): Path to the original ASR manifest file. + target_dir (str, optional): Output directory where tarred files and manifests will be saved. Defaults to "./tarred/". + num_workers (int, optional): Number of parallel worker processes for writing tar files. Defaults to 0 (sequential processing). + buckets_num (int, optional): Number of buckets for static bucketing. Defaults to 1 (no bucketing). + dynamic_buckets_num (int, optional): Number of buckets to estimate for dynamic bucketing. Defaults to 30. + only_manifests (bool, optional): If True, performs a dry run without creating actual tar files. Defaults to False. + + Raises: + ValueError: If the configuration has not been set. + FileNotFoundError: If the manifest file does not exist. + + Output: + - Creates tar files and a tarred dataset compatible manifest file in the specified `target_dir`. + - Preserves a record of the metadata used to construct the tarred dataset in `metadata.yaml`. + - Optionally creates shard manifests if `config.shard_manifests` is enabled. + + Notes: + - The function reads the manifest, applies filtering and shuffling if specified, and creates shards of tar files. + - It generates shard manifests and the main tarred dataset manifest. + - Metadata is updated and saved based on the tarred dataset configuration. + """ + if self.config is None: + raise ValueError("Config has not been set. Please call `configure(config: ASRTarredDatasetConfig)`") + + if manifest_path is None: + raise FileNotFoundError("Manifest filepath cannot be None !") + + config = self.config # type: ASRTarredDatasetConfig + + if not os.path.exists(target_dir): + os.makedirs(target_dir) + + # Read the existing manifest + entries, total_duration, filtered_entries, filtered_duration = self._read_manifest(manifest_path, config) + + header = [ + "Min.\nduration", + "Max.\nduration", + "Entries amount\nafter filtration", + "Total duration\nafter filtration", + "Shards\namount", + "Entries\nper shard", + "Remainded\nentries", + ] + + entires_amount = f'{len(entries)} / {len(entries) + len(filtered_entries)}' + entries_duration = f'{total_duration:.2f} / {total_duration + filtered_duration:.2f} s' + entries_per_shard = len(entries) // config.num_shards + remainder = len(entries) % config.num_shards + + data = [ + [ + f"{config.min_duration} s", + f"{config.max_duration} s", + f"{entires_amount}", + f"{entries_duration}", + f"{config.num_shards}", + f"{entries_per_shard}", + f"{remainder}", + ] + ] + + print('\n' + tabulate(data, headers=header, tablefmt="grid", colalign=["center"] * len(header))) + if dry_run: + return + + if len(entries) == 0: + print("No tarred dataset was created as there were 0 valid samples after filtering!") + return + if config.shuffle: + random.seed(config.shuffle_seed) + print(f"Shuffling (seed: {config.shuffle_seed})...") + if config.keep_files_together: + filename_entries = defaultdict(list) + for ent in entries: + filename_entries[ent["audio_filepath"]].append(ent) + filenames = list(filename_entries.keys()) + random.shuffle(filenames) + shuffled_entries = [] + for filename in filenames: + shuffled_entries += filename_entries[filename] + entries = shuffled_entries + else: + random.shuffle(entries) + + start_indices = [] + end_indices = [] + # Build indices + for i in range(config.num_shards): + start_idx = (len(entries) // config.num_shards) * i + end_idx = start_idx + (len(entries) // config.num_shards) + print(f"Shard {i} has entries {start_idx} ~ {end_idx}") + files = set() + for ent_id in range(start_idx, end_idx): + files.add(entries[ent_id]["audio_filepath"]) + print(f"Shard {i} contains {len(files)} files") + if i == config.num_shards - 1: + # We discard in order to have the same number of entries per shard. + print(f"Have {len(entries) - end_idx} entries left over that will be discarded.") + + start_indices.append(start_idx) + end_indices.append(end_idx) + + manifest_folder, _ = os.path.split(manifest_path) + + with Parallel(n_jobs=num_workers, verbose=config.num_shards) as parallel: + # Call parallel tarfile construction + new_entries_list = parallel( + delayed(self._create_shard)(entries[start_idx:end_idx], target_dir, i, manifest_folder, only_manifests) + for i, (start_idx, end_idx) in enumerate(zip(start_indices, end_indices)) + ) + + if config.shard_manifests: + sharded_manifests_dir = target_dir + '/sharded_manifests' + if not os.path.exists(sharded_manifests_dir): + os.makedirs(sharded_manifests_dir) + + for manifest in new_entries_list: + shard_id = manifest[0]['shard_id'] + new_manifest_shard_path = os.path.join(sharded_manifests_dir, f'manifest_{shard_id}.json') + with open(new_manifest_shard_path, 'w', encoding='utf-8') as m2: + for entry in manifest: + json.dump(entry, m2, ensure_ascii=False) + m2.write('\n') + + # Flatten the list of list of entries to a list of entries + new_entries = [sample for manifest in new_entries_list for sample in manifest] + del new_entries_list + + print("Total number of entries in manifest :", len(new_entries)) + + # Write manifest + new_manifest_path = os.path.join(target_dir, 'tarred_audio_manifest.json') + with open(new_manifest_path, 'w', encoding='utf-8') as m2: + for entry in new_entries: + json.dump(entry, m2, ensure_ascii=False) + m2.write('\n') + + # Write metadata (default metadata for new datasets) + new_metadata_path = os.path.join(target_dir, 'metadata.yaml') + metadata = ASRTarredDatasetMetadata() + + # Update metadata + metadata.dataset_config = config + metadata.num_samples_per_shard = len(new_entries) // config.num_shards + + if buckets_num <= 1: + # Estimate and update dynamic bucketing args + bucketing_kwargs = self.estimate_dynamic_bucketing_duration_bins( + new_manifest_path, num_buckets=dynamic_buckets_num + ) + for k, v in bucketing_kwargs.items(): + setattr(metadata.dataset_config, k, v) + + # Write metadata + metadata_yaml = OmegaConf.structured(metadata) + OmegaConf.save(metadata_yaml, new_metadata_path, resolve=True) + + def estimate_dynamic_bucketing_duration_bins(self, manifest_path: str, num_buckets: int = 30) -> dict: + from lhotse import CutSet + from lhotse.dataset.sampling.dynamic_bucketing import estimate_duration_buckets + + from nemo.collections.common.data.lhotse.nemo_adapters import LazyNeMoIterator + + cuts = CutSet(LazyNeMoIterator(manifest_path, metadata_only=True)) + bins = estimate_duration_buckets(cuts, num_buckets=num_buckets) + print( + f"Note: we estimated the optimal bucketing duration bins for {num_buckets} buckets. " + "You can enable dynamic bucketing by setting the following options in your training script:\n" + " use_lhotse=true\n" + " use_bucketing=true\n" + f" num_buckets={num_buckets}\n" + f" bucket_duration_bins=[{','.join(map(str, bins))}]\n" + " batch_duration=\n" + "If you'd like to use a different number of buckets, re-estimate this option manually using " + "scripts/speech_recognition/estimate_duration_bins.py" + ) + return dict( + use_lhotse=True, + use_bucketing=True, + num_buckets=num_buckets, + bucket_duration_bins=list(map(float, bins)), # np.float -> float for YAML serialization + ) + + def create_concatenated_dataset( + self, + base_manifest_path: str, + manifest_paths: List[str], + metadata: ASRTarredDatasetMetadata, + target_dir: str = "./tarred_concatenated/", + num_workers: int = 1, + only_manifests: bool = False, + dry_run: bool = False, + ): + """ + Creates a concatenated tarred dataset from the base manifest and additional manifest files. + + Args: + base_manifest_path (str): Path to the base manifest file that contains information for the original + tarred dataset (with flattened paths). + manifest_paths (List[str]): List of paths to additional manifest files that will be concatenated with + the base tarred dataset. + metadata (ASRTarredDatasetMetadata): Metadata instance containing configuration and overrides. + target_dir (str, optional): Output directory where tarred files and manifests will be saved. Defaults to "./tarred_concatenated/". + num_workers (int, optional): Number of parallel worker processes for creating tar files. Defaults to 1. + only_manifests (bool, optional): If True, performs a dry run without creating actual tar files. Defaults to False. + + Raises: + FileNotFoundError: If the base manifest file or any of the additional manifest files does not exist. + + Output: + - Creates tar files and a concatenated tarred dataset compatible manifest file in the specified `target_dir`. + - Updates metadata to reflect the concatenated dataset, including the version and historical data. + + Notes: + - The function reads the base manifest and additional manifests, filters and shuffles entries as needed, + and creates new shards of tar files. + - It generates a new concatenated dataset manifest and updates metadata with versioning and historical context. + - If `metadata` is provided, the function updates its version and includes historical data in the new metadata. + """ + if not os.path.exists(target_dir): + os.makedirs(target_dir) + + if base_manifest_path is None: + raise FileNotFoundError("Base manifest filepath cannot be None !") + + if manifest_paths is None or len(manifest_paths) == 0: + raise FileNotFoundError("List of additional manifest filepaths cannot be None !") + + config = ASRTarredDatasetConfig(**(metadata.dataset_config)) + + # Read the existing manifest (no filtering here) + base_entries, _, _, _ = self._read_manifest(base_manifest_path, config) + print(f"Read base manifest containing {len(base_entries)} samples.") + + # Precompute number of samples per shard + if metadata.num_samples_per_shard is None: + num_samples_per_shard = len(base_entries) // config.num_shards + else: + num_samples_per_shard = metadata.num_samples_per_shard + + print("Number of samples per shard :", num_samples_per_shard) + + # Compute min and max duration and update config (if no metadata passed) + print(f"Selected max duration : {config.max_duration}") + print(f"Selected min duration : {config.min_duration}") + + entries = [] + for new_manifest_idx in range(len(manifest_paths)): + new_entries, total_duration, filtered_new_entries, filtered_duration = self._read_manifest( + manifest_paths[new_manifest_idx], config + ) + + if len(filtered_new_entries) > 0: + print( + f"Filtered {len(filtered_new_entries)} files which amounts to {filtered_duration:0.2f}" + f" seconds of audio from manifest {manifest_paths[new_manifest_idx]}." + ) + print( + f"After filtering, manifest has {len(entries)} files which amounts to {total_duration} seconds of audio." + ) + + entries.extend(new_entries) + + if len(entries) == 0: + print("No tarred dataset was created as there were 0 valid samples after filtering!") + return + + if config.shuffle: + random.seed(config.shuffle_seed) + print(f"Shuffling (seed: {config.shuffle_seed})...") + random.shuffle(entries) + + # Drop last section of samples that cannot be added onto a chunk + drop_count = len(entries) % num_samples_per_shard + total_new_entries = len(entries) + entries = entries[:-drop_count] + + print( + f"Dropping {drop_count} samples from total new samples {total_new_entries} since they cannot " + f"be added into a uniformly sized chunk." + ) + + # Create shards and updated manifest entries + num_added_shards = len(entries) // num_samples_per_shard + + print(f"Number of samples in base dataset : {len(base_entries)}") + print(f"Number of samples in additional datasets : {len(entries)}") + print(f"Number of added shards : {num_added_shards}") + print(f"Remainder: {len(entries) % num_samples_per_shard}") + + if dry_run: + return + + start_indices = [] + end_indices = [] + shard_indices = [] + for i in range(num_added_shards): + start_idx = (len(entries) // num_added_shards) * i + end_idx = start_idx + (len(entries) // num_added_shards) + shard_idx = i + config.num_shards + print(f"Shard {shard_idx} has entries {start_idx + len(base_entries)} ~ {end_idx + len(base_entries)}") + + start_indices.append(start_idx) + end_indices.append(end_idx) + shard_indices.append(shard_idx) + + manifest_folder, _ = os.path.split(base_manifest_path) + + with Parallel(n_jobs=num_workers, verbose=num_added_shards) as parallel: + # Call parallel tarfile construction + new_entries_list = parallel( + delayed(self._create_shard)( + entries[start_idx:end_idx], target_dir, shard_idx, manifest_folder, only_manifests + ) + for i, (start_idx, end_idx, shard_idx) in enumerate(zip(start_indices, end_indices, shard_indices)) + ) + + if config.shard_manifests: + sharded_manifests_dir = target_dir + '/sharded_manifests' + if not os.path.exists(sharded_manifests_dir): + os.makedirs(sharded_manifests_dir) + + for manifest in new_entries_list: + shard_id = manifest[0]['shard_id'] + new_manifest_shard_path = os.path.join(sharded_manifests_dir, f'manifest_{shard_id}.json') + with open(new_manifest_shard_path, 'w', encoding='utf-8') as m2: + for entry in manifest: + json.dump(entry, m2, ensure_ascii=False) + m2.write('\n') + + # Flatten the list of list of entries to a list of entries + new_entries = [sample for manifest in new_entries_list for sample in manifest] + del new_entries_list + + # Write manifest + if metadata is None: + new_version = 1 # start with `1`, where `0` indicates the base manifest + dataset + else: + new_version = metadata.version + 1 + + print("Total number of entries in manifest :", len(base_entries) + len(new_entries)) + + new_manifest_path = os.path.join(target_dir, f'tarred_audio_manifest_version_{new_version}.json') + with open(new_manifest_path, 'w', encoding='utf-8') as m2: + # First write all the entries of base manifest + for entry in base_entries: + json.dump(entry, m2, ensure_ascii=False) + m2.write('\n') + + # Finally write the new entries + for entry in new_entries: + json.dump(entry, m2, ensure_ascii=False) + m2.write('\n') + + # Preserve historical metadata + base_metadata = metadata + + # Write metadata (updated metadata for concatenated datasets) + new_metadata_path = os.path.join(target_dir, f'metadata_version_{new_version}.yaml') + metadata = ASRTarredDatasetMetadata() + + # Update config + config.num_shards = config.num_shards + num_added_shards + + # Update metadata + metadata.version = new_version + metadata.dataset_config = config + metadata.num_samples_per_shard = num_samples_per_shard + metadata.is_concatenated_manifest = True + metadata.created_datetime = metadata.get_current_datetime() + + # Attach history + current_metadata = OmegaConf.structured(base_metadata.history) + metadata.history = current_metadata + + # Write metadata + metadata_yaml = OmegaConf.structured(metadata) + OmegaConf.save(metadata_yaml, new_metadata_path, resolve=True) + + def _read_manifest(self, manifest_path: str, config: ASRTarredDatasetConfig): + """Read and filters data from the manifest""" + # Read the existing manifest + entries = [] + total_duration = 0.0 + filtered_entries = [] + filtered_duration = 0.0 + with open(manifest_path, 'r', encoding='utf-8') as m: + for line in m: + entry = json.loads(line) + audio_key = "audio_filepath" if "audio_filepath" in entry else "audio_file" + if config.slice_with_offset and "offset" not in entry: + raise KeyError( + f"Manifest entry does not contain 'offset' field, but '--slice_with_offset' is enabled: {entry}" + ) + if audio_key not in entry: + raise KeyError(f"Manifest entry does not contain 'audio_filepath' or 'audio_file' key: {entry}") + audio_filepath = entry[audio_key] + if not os.path.isfile(audio_filepath) and not os.path.isabs(audio_filepath): + audio_filepath_abs = os.path.join(os.path.dirname(manifest_path), audio_filepath) + if not os.path.isfile(audio_filepath_abs): + raise FileNotFoundError(f"Could not find {audio_filepath} or {audio_filepath_abs}!") + entry[audio_key] = audio_filepath_abs + if (config.max_duration is None or entry['duration'] < config.max_duration) and ( + config.min_duration is None or entry['duration'] >= config.min_duration + ): + entries.append(entry) + total_duration += entry["duration"] + else: + filtered_entries.append(entry) + filtered_duration += entry['duration'] + + return entries, total_duration, filtered_entries, filtered_duration + + def _write_to_tar( + self, tar, audio_filepath: str, squashed_filename: str, duration: float = None, offset: float = 0 + ) -> None: + codec = self.config.force_codec + to_transcode = not (codec is None or audio_filepath.endswith(f".{codec}")) + to_crop = not (duration is None and offset == 0) + + if not to_crop and not to_transcode: + # Add existing file without transcoding, trimming, or re-encoding. + tar.add(audio_filepath, arcname=squashed_filename) + return + + # Standard processing: read, trim, and transcode the audio file + with sf.SoundFile(audio_filepath) as f: + sampling_rate = f.samplerate + + # Trim audio based on offset and duration. + start_sample = int(offset * sampling_rate) + num_frames = int(duration * sampling_rate) if duration else -1 + audio, sampling_rate = sf.read(audio_filepath, start=start_sample, frames=num_frames) + + # Determine codec parameters. + if codec is not None: + if codec == "opus": + kwargs = {"format": "ogg", "subtype": "opus"} + else: + kwargs = {"format": codec} + else: + codec = sf.info(audio_filepath).format.lower() + kwargs = {"format": codec} + + # Transcode and write audio to tar. + encoded_audio = BytesIO() + sf.write(encoded_audio, audio, sampling_rate, closefd=False, **kwargs) + + # Generate filename with the appropriate extension. + encoded_squashed_filename = f"{squashed_filename.split('.')[0]}.{codec}" + + # Add the in-memory audio file to the tar archive. + ti = tarfile.TarInfo(encoded_squashed_filename) + encoded_audio.seek(0) + ti.size = len(encoded_audio.getvalue()) + tar.addfile(ti, encoded_audio) + + def _create_shard(self, entries, target_dir, shard_id, manifest_folder: str = None, only_manifests: bool = False): + """Creates a tarball containing the audio files from `entries`.""" + if self.config.sort_in_shards: + entries.sort(key=lambda x: x["duration"], reverse=False) + + new_entries = [] + + tar_filepath = os.path.join(target_dir, f'audio_{shard_id}.tar') + if not only_manifests: + tar = tarfile.open(tar_filepath, mode='w', dereference=True) + + count = dict() + for entry in tqdm(entries, desc="Creating shard.."): + # We squash the filename since we do not preserve directory structure of audio files in the tarball. + if os.path.exists(entry["audio_filepath"]) or only_manifests: + audio_filepath = entry["audio_filepath"] + else: + if not manifest_folder: + raise FileNotFoundError(f"Could not find {entry['audio_filepath']}!") + + audio_filepath = os.path.join(manifest_folder, entry["audio_filepath"]) + if not os.path.exists(audio_filepath): + raise FileNotFoundError(f"Could not find {entry['audio_filepath']}!") + + base, ext = os.path.splitext(audio_filepath) + base = base.replace('/', '_') + # Need the following replacement as long as WebDataset splits on first period + base = base.replace('.', '_') + squashed_filename = f'{base}{ext}' + + if self.config.slice_with_offset: + if squashed_filename not in count: + count[squashed_filename] = 1 + + entry_offset = str(entry['offset']).split('.') + if len(entry_offset) == 1: + # Example: offset = 12 -> becomes 12_0 + entry_offset.append('0') + elif len(entry_offset) == 2: + # Example: offset = 12.34 -> becomes 12_34 + pass + else: + raise ValueError( + f"The offset for the entry with audio_filepath '{entry['audio_filepath']}' is incorrectly provided ({entry['offset']}). " + "Expected a float-like value (e.g., 12 or 12.34)." + ) + entry_offset = "_".join(entry_offset) + + entry_duration = str(entry['duration']).split('.') + if len(entry_duration) == 1: + entry_duration.append('0') + elif len(entry_duration) > 2: + raise ValueError( + f"The duration for the entry with audio_filepath '{entry['audio_filepath']}' is incorrectly provided ({entry['duration']})." + ) + entry_duration = "_".join(entry_duration) + + to_write = base + "_" + entry_offset + "_" + entry_duration + ext + if not only_manifests: + self._write_to_tar( + tar, audio_filepath, to_write, duration=entry['duration'], offset=entry['offset'] + ) + count[squashed_filename] += 1 + + entry['source_audio_offset'] = entry['offset'] + del entry['offset'] + else: + if squashed_filename not in count: + if not only_manifests: + self._write_to_tar(tar, audio_filepath, squashed_filename) + to_write = squashed_filename + count[squashed_filename] = 1 + else: + to_write = base + "-sub" + str(count[squashed_filename]) + ext + count[squashed_filename] += 1 + + if only_manifests: + entry['abs_audio_filepath'] = audio_filepath + + # Carry over every key in the entry, override audio_filepath and shard_id + new_entry = { + **entry, + 'audio_filepath': to_write, + 'shard_id': shard_id, # Keep shard ID for recordkeeping + } + new_entries.append(new_entry) + + if not only_manifests: + tar.close() + return new_entries + + @classmethod + def setup_history(cls, base_metadata: ASRTarredDatasetMetadata, history: List[Any]): + if 'history' in base_metadata.keys(): + for history_val in base_metadata.history: + cls.setup_history(history_val, history) + + if base_metadata is not None: + metadata_copy = copy.deepcopy(base_metadata) + with open_dict(metadata_copy): + metadata_copy.pop('history', None) + history.append(metadata_copy) + + +def main(args): + if args.buckets_num > 1: + bucket_length = (args.max_duration - args.min_duration) / float(args.buckets_num) + for i_bucket in range(args.buckets_num): + bucket_config = copy.deepcopy(args) + bucket_config.min_duration = args.min_duration + i_bucket * bucket_length + bucket_config.max_duration = bucket_config.min_duration + bucket_length + if i_bucket == args.buckets_num - 1: + # add a small number to cover the samples with exactly duration of max_duration in the last bucket. + bucket_config.max_duration += 1e-5 + bucket_config.target_dir = os.path.join(args.target_dir, f"bucket{i_bucket+1}") + print( + f"Creating bucket {i_bucket+1} with min_duration={bucket_config.min_duration} and max_duration={bucket_config.max_duration} ..." + ) + print(f"Results are being saved at: {bucket_config.target_dir}.") + create_tar_datasets(**vars(bucket_config)) + if not args.dry_run: + print(f"Bucket {i_bucket+1} is created.") + else: + create_tar_datasets(**vars(args)) + + +def create_tar_datasets( + manifest_path: str = None, + concat_manifest_paths: str = None, + target_dir: str = None, + metadata_path: str = None, + num_shards: int = -1, + max_duration: float = None, + min_duration: float = None, + shuffle: bool = False, + keep_files_together: bool = False, + sort_in_shards: bool = False, + buckets_num: int = 1, + dynamic_buckets_num: int = 30, + shuffle_seed: int = None, + write_metadata: bool = False, + no_shard_manifests: bool = False, + force_codec: str = None, + workers: int = 1, + slice_with_offset: bool = False, + only_manifests: bool = False, + dry_run: bool = False, +): + builder = ASRTarredDatasetBuilder() + + shard_manifests = False if no_shard_manifests else True + + if write_metadata: + metadata = ASRTarredDatasetMetadata() + dataset_cfg = ASRTarredDatasetConfig( + num_shards=num_shards, + shuffle=shuffle, + max_duration=max_duration, + min_duration=min_duration, + shuffle_seed=shuffle_seed, + sort_in_shards=sort_in_shards, + shard_manifests=shard_manifests, + keep_files_together=keep_files_together, + force_codec=force_codec, + slice_with_offset=slice_with_offset, + ) + metadata.dataset_config = dataset_cfg + + output_path = os.path.join(target_dir, 'default_metadata.yaml') + OmegaConf.save(metadata, output_path, resolve=True) + print(f"Default metadata written to {output_path}") + exit(0) + + if concat_manifest_paths is None or len(concat_manifest_paths) == 0: + # Create a tarred dataset from scratch + config = ASRTarredDatasetConfig( + num_shards=num_shards, + shuffle=shuffle, + max_duration=max_duration, + min_duration=min_duration, + shuffle_seed=shuffle_seed, + sort_in_shards=sort_in_shards, + shard_manifests=shard_manifests, + keep_files_together=keep_files_together, + force_codec=force_codec, + slice_with_offset=slice_with_offset, + ) + builder.configure(config) + builder.create_new_dataset( + manifest_path=manifest_path, + target_dir=target_dir, + num_workers=workers, + buckets_num=buckets_num, + dynamic_buckets_num=dynamic_buckets_num, + only_manifests=only_manifests, + dry_run=dry_run, + ) + + else: + if buckets_num > 1: + raise ValueError("Concatenation feature does not support buckets_num > 1.") + print("Concatenating multiple tarred datasets ...") + + # Implicitly update config from base details + if metadata_path is not None: + metadata = ASRTarredDatasetMetadata.from_file(metadata_path) + else: + raise ValueError("`metadata` yaml file path must be provided!") + + # Preserve history + history = [] + builder.setup_history(OmegaConf.structured(metadata), history) + metadata.history = history + + # Add command line overrides (everything other than num_shards) + metadata.dataset_config.max_duration = max_duration + metadata.dataset_config.min_duration = min_duration + metadata.dataset_config.shuffle = shuffle + metadata.dataset_config.shuffle_seed = shuffle_seed + metadata.dataset_config.sort_in_shards = sort_in_shards + metadata.dataset_config.shard_manifests = shard_manifests + + builder.configure(metadata.dataset_config) + + # Concatenate a tarred dataset onto a previous one + builder.create_concatenated_dataset( + base_manifest_path=manifest_path, + manifest_paths=concat_manifest_paths, + metadata=metadata, + target_dir=target_dir, + num_workers=workers, + slice_with_offset=slice_with_offset, + only_manifests=only_manifests, + dry_run=dry_run, + ) + + if not dry_run and (DALI_INDEX_SCRIPT_AVAILABLE and dali_index.INDEX_CREATOR_AVAILABLE): + print("Constructing DALI Tarfile Index - ", target_dir) + index_config = dali_index.DALITarredIndexConfig(tar_dir=target_dir, workers=workers) + dali_index.main(index_config) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Convert an existing ASR dataset to tarballs compatible with TarredAudioToTextDataLayer." + ) + parser.add_argument( + "--manifest_path", default=None, type=str, required=False, help="Path to the existing dataset's manifest." + ) + + parser.add_argument( + '--concat_manifest_paths', + nargs='+', + default=None, + type=str, + required=False, + help="Path to the additional dataset's manifests that will be concatenated with base dataset.", + ) + + # Optional arguments + parser.add_argument( + "--target_dir", + default='./tarred', + type=str, + help="Target directory for resulting tarballs and manifest. Defaults to `./tarred`. Creates the path if necessary.", + ) + + parser.add_argument( + "--metadata_path", + required=False, + default=None, + type=str, + help="Path to metadata file for the dataset.", + ) + + parser.add_argument( + "--num_shards", + default=-1, + type=int, + help="Number of shards (tarballs) to create. Used for partitioning data among workers.", + ) + parser.add_argument( + '--max_duration', + default=None, + required=True, + type=float, + help='Maximum duration of audio clip in the dataset. By default, it is None and is required to be set.', + ) + parser.add_argument( + '--min_duration', + default=None, + type=float, + help='Minimum duration of audio clip in the dataset. By default, it is None and will not filter files.', + ) + parser.add_argument( + "--shuffle", + action='store_true', + help="Whether or not to randomly shuffle the samples in the manifest before tarring/sharding.", + ) + + parser.add_argument( + "--keep_files_together", + action='store_true', + help="Whether or not to keep entries from the same file (but different offsets) together when sorting before tarring/sharding.", + ) + parser.add_argument( + "--slice_with_offset", + action='store_true', + help=( + "If set, the audio will be sliced based on `offset` and `duration` fields from the manifest. " + "This is useful for creating datasets from audio segments instead of full files. " + "When unset, the entire audio file is used without slicing, regardless of the offset/duration values in the manifest." + ), + ) + parser.add_argument( + "--sort_in_shards", + action='store_true', + help="Whether or not to sort samples inside the shards based on their duration.", + ) + + parser.add_argument( + "--buckets_num", + type=int, + default=1, + help="Number of buckets to create based on duration.", + ) + + parser.add_argument( + "--dynamic_buckets_num", + type=int, + default=30, + help="Intended for dynamic (on-the-fly) bucketing; this option will not bucket your dataset during tar conversion. " + "Estimates optimal bucket duration bins for a given number of buckets.", + ) + + parser.add_argument("--shuffle_seed", type=int, default=None, help="Random seed for use if shuffling is enabled.") + parser.add_argument( + '--write_metadata', + action='store_true', + help=( + "Flag to write a blank metadata with the current call config. " + "Note that the metadata will not contain the number of shards, " + "and it must be filled out by the user." + ), + ) + parser.add_argument( + "--no_shard_manifests", + action='store_true', + help="Do not write sharded manifests along with the aggregated manifest.", + ) + parser.add_argument( + "--force_codec", + type=str, + default=None, + help=( + "If specified, transcode the audio to the given format. " + "Supports libnsndfile formats (example values: 'opus', 'flac')." + ), + ) + parser.add_argument( + "--only_manifests", + action='store_true', + help=( + "If set, only creates manifests for each shard without creating the actual tar files. " + "This allows you to verify the output structure and content before committing to the full tarball creation process. " + "Each manifest entry will also include the field `abs_audio_filepath`, which stores the absolute path to the original audio file." + ), + ) + parser.add_argument( + "--dry_run", + action='store_true', + help=( + "Run in simulation mode: calculate and display the number of shards and estimated data per shard without reading audio files or writing any output." + ), + ) + parser.add_argument('--workers', type=int, default=1, help='Number of worker processes') + args = parser.parse_args() + main(args) \ No newline at end of file diff --git a/sdp/processors/manage_files/utils/create_dali_tarred_dataset_index.py b/sdp/processors/manage_files/utils/create_dali_tarred_dataset_index.py new file mode 100644 index 00000000..1ae64dc5 --- /dev/null +++ b/sdp/processors/manage_files/utils/create_dali_tarred_dataset_index.py @@ -0,0 +1,95 @@ +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import glob +import logging +import os +from dataclasses import dataclass + +import hydra +from hydra.core.config_store import ConfigStore +from joblib import Parallel, delayed +from omegaconf import MISSING + +try: + from wds2idx import IndexCreator + + INDEX_CREATOR_AVAILABLE = True +except (ImportError, ModuleNotFoundError): + INDEX_CREATOR_AVAILABLE = False + +""" +python create_dali_tarred_dataset_index.py \ + tar_dir= \ + workers=-1 + +""" + +logging.basicConfig(level=logging.INFO) + + +@dataclass +class DALITarredIndexConfig: + tar_dir: str = MISSING # Path to the existing dataset's manifest + workers: int = -1 # number of worker processes + + +def process_index_path(tar_paths, index_dir): + """ + Appends the folder `{index_dir}` to the filepath of all tarfiles. + Example: + /X/Y/Z/audio_0.tar -> /X/Y/Z/{index_dir}/audio_0.index + """ + index_paths = [] + for path in tar_paths: + basepath, filename = os.path.split(path) + path = filename.replace('.tar', '.index') + path = os.path.join(basepath, path) + base, name = os.path.split(path) + index_path = os.path.join(index_dir, name) + index_paths.append(index_path) + + return index_paths + + +def build_index(tarpath, indexfile): + with IndexCreator(tarpath, indexfile) as index: + index.create_index() + + +@hydra.main(config_path=None, config_name='index_config', version_base="1.1") +def main(cfg: DALITarredIndexConfig): + if not INDEX_CREATOR_AVAILABLE: + logging.error("`wds2idx` is not installed. Please install NVIDIA DALI >= 1.11") + exit(1) + + tar_files = list(glob.glob(os.path.join(cfg.tar_dir, "*.tar"))) + + index_dir = os.path.join(cfg.tar_dir, "dali_index") + if not os.path.exists(index_dir): + os.makedirs(index_dir, exist_ok=True) + + index_paths = process_index_path(tar_files, index_dir) + + with Parallel(n_jobs=cfg.workers, verbose=len(tar_files)) as parallel: + _ = parallel(delayed(build_index)(tarpath, indexfile) for tarpath, indexfile in zip(tar_files, index_paths)) + + logging.info("Finished constructing index files !") + + +ConfigStore.instance().store(name='index_config', node=DALITarredIndexConfig) + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/sdp/processors/modify_manifest/common.py b/sdp/processors/modify_manifest/common.py index 98ad1fa3..be16892c 100644 --- a/sdp/processors/modify_manifest/common.py +++ b/sdp/processors/modify_manifest/common.py @@ -364,40 +364,83 @@ def process(self): fout.write(json.dumps(new_line, ensure_ascii=False) + "\n") -class ApplyInnerJoin(BaseProcessor): - """Applies inner join to two manifests, i.e. creates a manifest from records that have matching values in both manifests. - For more information, please refer to the Pandas merge function documentation: - https://pandas.pydata.org/docs/reference/api/pandas.merge.html#pandas.merge +class JoinManifests(BaseProcessor): + """ + Applies a configurable join operation to two input manifests using `pandas.merge`. + + This processor reads two manifest files (lists of JSON records), converts them to pandas DataFrames, + and performs a join (inner, outer, left, or right) based on the specified merge parameters. + It supports flexible control over the merging behavior via the `merge_params` dictionary. + For available options, refer to: + https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.merge.html Args: - column_id (Union[str, List[str], None]): Field names to join on. These must be found in both manifests. - If `column_id` is None then this defaults to the intersection of the columns in both manifests. - Defaults to None. - left_manifest_file (Optional[str]): path to the left manifest. Defaults to `input_manifest_file`. - right_manifest_file (str): path to the right manifest. + right_manifest_file (str): Path to the right manifest file to join. + left_manifest_file (Optional[str]): Path to the left manifest file to join. + If not provided, defaults to `input_manifest_file`. + merge_params (Dict): Dictionary of parameters passed directly to `pandas.merge`, such as: + - `on`: Column name or list of column names to join on. + - `how`: Type of join to perform: 'left', 'right', 'outer', or 'inner'. + - `suffixes`: Suffixes to apply to overlapping column names in the left and right DataFrames. + - `validate`: Check whether the merge is of a specified type (e.g., "one_to_one"). Returns: - Inner join of two manifests. + A merged manifest file in JSON format, written to `output_manifest_file`. """ def __init__( self, right_manifest_file: str, left_manifest_file: Optional[str] = None, - column_id: Union[str, List[str], None] = None, + merge_params: Dict = {}, **kwargs, ): super().__init__(**kwargs) self.left_manifest_file = left_manifest_file if left_manifest_file != None else self.input_manifest_file self.right_manifest_file = right_manifest_file - self.column_id = column_id + self.merge_params = merge_params def process(self): m1 = pd.DataFrame.from_records(load_manifest(Path(self.left_manifest_file))) m2 = pd.DataFrame.from_records(load_manifest(Path(self.right_manifest_file))) - m3 = pd.merge(m1, m2, on=self.column_id, how="inner") + m3 = pd.merge(m1, m2, **self.merge_params) with open(self.output_manifest_file, "wt", encoding="utf8") as fout: for _, line in m3.iterrows(): fout.write(json.dumps(dict(line), ensure_ascii=False) + "\n") + + +class DropSpecifiedFields(BaseProcessor): + """ + A processor that removes specified fields from each data entry in the manifest. + + This processor reads an input manifest line by line, drops the fields listed in `fields_to_drop` + from each JSON entry, and writes the cleaned entries to the output manifest. + + Args: + fields_to_drop (List[str]): A list of keys to remove from each manifest entry. + **kwargs: Additional arguments passed to the BaseProcessor (e.g., input/output manifest paths). + + Returns: + A line-delimited JSON manifest, where each entry is the same as the input, + but with the specified fields removed. + """ + + def __init__(self, fields_to_drop: List[str], **kwargs): + super().__init__(**kwargs) + self.fields_to_drop = fields_to_drop + + def process(self): + # Open the input and output manifest files + with open(self.input_manifest_file, "rt", encoding="utf8") as fin, open( + self.output_manifest_file, "wt", encoding="utf8" + ) as fout: + # Iterate over each line (entry) in the input manifest + for line in tqdm(fin): + # Parse JSON entry from the current line + entry = json.loads(line) + # Create a new entry by excluding the specified fields + new_line = {field: entry[field] for field in entry if field not in self.fields_to_drop} + # Write the cleaned entry to the output manifest + fout.write(json.dumps(new_line, ensure_ascii=False) + "\n") diff --git a/sdp/processors/modify_manifest/data_to_data.py b/sdp/processors/modify_manifest/data_to_data.py index 16e1de6d..b64e879e 100644 --- a/sdp/processors/modify_manifest/data_to_data.py +++ b/sdp/processors/modify_manifest/data_to_data.py @@ -15,12 +15,18 @@ import collections import os import re -from typing import Dict, List, Optional +import tempfile +import shutil +import requests +import wget +import yaml +import tarfile +from glob import glob +from typing import Dict, List import soundfile import torchaudio from docx import Document -from sox import Transformer from tqdm import tqdm import json @@ -30,7 +36,7 @@ BaseProcessor, DataEntry, ) -from sdp.utils.common import ffmpeg_convert +from sdp.utils.apply_operators import evaluate_expression from sdp.utils.edit_spaces import add_start_end_spaces, remove_extra_spaces from sdp.utils.get_diff import get_diff_with_subs_grouped from sdp.utils.metrics_computation import ( @@ -76,78 +82,6 @@ def process_dataset_entry(self, data_entry): return [DataEntry(data=data_entry)] -class FfmpegConvert(BaseParallelProcessor): - """ - Processor for converting video or audio files to audio using FFmpeg and updating the dataset with the path to the resampled audio. - If ``id_key`` is not None, the output file path will be ``/.wav``. - If ``id_key`` is None, the output file path will be ``/.wav``. - - .. note:: ``id_key`` can be used to create subdirectories inside ``resampled_audio_dir`` (by using forward slashes ``/``). - e.g. if ``id_key`` takes the form ``dir_name1/dir_name2/filename``, the output file path will be - - ``/dir_name1/dirname2/filename.wav``. - - Args: - converted_audio_dir (str): The directory to store the resampled audio files. - input_file_key (str): The field in the dataset representing the path to the input video or audio files. - output_file_key (str): The field in the dataset representing the path to the resampled audio files with ``output_format``. If ``id_key`` is None, the output file path will be ``/.wav``. - id_key (str): (Optional) The field in the dataset representing the unique ID or identifier for each entry. If ``id_key`` is not None, the output file path will be ``/.wav``. Defaults to None. - output_format (str): (Optional) Format of the output audio files. Defaults to `wav`. - target_samplerate (int): (Optional) The target sampling rate for the resampled audio. Defaults to 16000. - target_nchannels (int): (Optional) The target number of channels for the resampled audio. Defaults to 1. - **kwargs: Additional keyword arguments to be passed to the base class `BaseParallelProcessor`. - - """ - - def __init__( - self, - converted_audio_dir: str, - input_file_key: str, - output_file_key: str, - id_key: str = None, - output_format: str = "wav", - base_dir: str = None, - target_samplerate: int = 16000, - target_nchannels: int = 1, - **kwargs, - ): - super().__init__(**kwargs) - self.converted_audio_dir = converted_audio_dir - self.input_file_key = input_file_key - self.output_file_key = output_file_key - self.output_format = output_format - self.id_key = id_key - self.base_dir = base_dir - self.target_samplerate = target_samplerate - self.target_nchannels = target_nchannels - - def prepare(self): - assert self.output_format == "wav", "Currently only wav format is supported" - os.makedirs(self.converted_audio_dir, exist_ok=True) - - def process_dataset_entry(self, data_entry): - input_file = data_entry[self.input_file_key] - if self.id_key: - key = data_entry[self.id_key] - os.makedirs(os.path.join(self.converted_audio_dir, *key.split("/")[:-1]), exist_ok=True) - else: - key = os.path.splitext(input_file)[0].split("/")[-1] - - if self.base_dir: - new_dir = os.path.dirname(os.path.relpath(input_file, self.base_dir)) - os.makedirs(os.path.join(self.converted_audio_dir, new_dir), exist_ok=True) - - key = os.path.join(new_dir, key) - - audio_file = os.path.join(self.converted_audio_dir, key) + "." + self.output_format - - if not os.path.isfile(audio_file): - ffmpeg_convert(input_file, audio_file, self.target_samplerate, self.target_nchannels) - - data_entry[self.output_file_key] = audio_file - return [DataEntry(data=data_entry)] - - class ReadTxtLines(BaseParallelProcessor): """ The text file specified in source_filepath will be read, and each line in it will be added as a line in the output manifest, @@ -183,109 +117,45 @@ def process_dataset_entry(self, data_entry): return data_list -class SoxConvert(BaseParallelProcessor): - """Processor for Sox to convert audio files to specified format. - - Args: - output_manifest_file (str): Path to the output manifest file. - input_audio_file_key (str): Key in the manifest file that contains the path to the input audio file. - output_audio_file_key (str): Key in the manifest file that contains the path to the output audio file. - converted_audio_dir (str): Path to the directory where the converted audio files will be stored. - output_format (str): Format of the output audio file. - rate (int): Sample rate of the output audio file. - channels (int): Number of channels of the output audio file. - workspace_dir (str, Optional): Path to the workspace directory. Defaults to None. - """ - - def __init__( - self, - converted_audio_dir: str, - input_audio_file_key: str = "audio_filepath", - output_audio_file_key: str = "audio_filepath", - output_format: str = "wav", - rate: int = 16000, - channels: int = 1, - workspace_dir: Optional[str] = None, - **kwargs, - ): - # Extract workspace_dir from kwargs to avoid passing it to BaseProcessor - if "workspace_dir" in kwargs: - workspace_dir = kwargs.pop("workspace_dir") - - super().__init__(**kwargs) - self.input_audio_file_key = input_audio_file_key - self.output_audio_file_key = output_audio_file_key - self.converted_audio_dir = converted_audio_dir - self.output_format = output_format - self.workspace_dir = workspace_dir - - # Store the new parameters for later use: - self.rate = rate - self.channels = channels - - def prepare(self): - # Debug print for workspace_dir - logger.info(f"SoxConvert workspace_dir: {self.workspace_dir}") - os.makedirs(self.converted_audio_dir, exist_ok=True) - - def process_dataset_entry(self, data_entry): - audio_path = data_entry[self.input_audio_file_key] - - # If workspace_dir is provided, join it with audio_path to get absolute path - if self.workspace_dir is not None: - full_audio_path = os.path.join(self.workspace_dir, audio_path) - else: - full_audio_path = audio_path - - # Debug print first file path - if not hasattr(self, '_debug_printed'): - logger.info(f"First audio_path from manifest: {audio_path}") - logger.info(f"First full_audio_path: {full_audio_path}") - logger.info(f"Path exists: {os.path.exists(full_audio_path)}") - self._debug_printed = True - - key = os.path.splitext(audio_path)[0].split("/")[-1] - converted_file = os.path.join(self.converted_audio_dir, key) + f".{self.output_format}" - - if not os.path.isfile(converted_file): - transformer = Transformer() - - transformer.rate(self.rate) - transformer.channels(self.channels) - - transformer.build(full_audio_path, converted_file) - - data_entry[self.output_audio_file_key] = converted_file - return [DataEntry(data=data_entry)] - - class CountNumWords(BaseParallelProcessor): """ - Processor for counting the number of words in the text_key field saving the number in num_words_key. + A processor that counts the number of words in the `text_key` field of each dataset entry and stores the result in `num_words_key`. + + Before counting, the text is optionally cleaned using a custom `alphabet`: + - If `alphabet` is provided, all characters not in the alphabet are replaced with whitespace. + - Consecutive whitespace characters are collapsed into a single space. + - The number of resulting space-separated tokens is counted as the number of words. Args: - text_key (str): The field containing the input text in the dataset. - num_words_key (str): The field to store the number of words in the dataset. - alphabet (str): Characters to be used to count words. Any other characters are substituted by whitespace and not take into account. - **kwargs: Additional keyword arguments to be passed to the base class `BaseParallelProcessor`. + text_key (str): The key in the input data entry containing the text to be analyzed. + num_words_key (str): The key under which the word count will be stored in the output entry. Defaults to "num_words". + alphabet (str, optional): A string of allowed characters (e.g., lowercase letters). All characters not in this set will be replaced with whitespace before counting. If not provided, no filtering is applied. + **kwargs: Additional arguments passed to the BaseParallelProcessor. + Returns: + A manifest where each entry is the original data entry with an added field `num_words_key` (default: `"num_words"`), + indicating the number of words in the `text_key` field. """ def __init__( self, text_key: str, - num_words_key: str, - alphabet: str, + num_words_key: str = "num_words", + alphabet: str = None, **kwargs, ): super().__init__(**kwargs) self.text_key = text_key self.num_words_key = num_words_key - self.pattern = re.compile("[^" + alphabet + "]") + self.pattern = None + if alphabet: + self.pattern = re.compile("[^" + alphabet + "]") def process_dataset_entry(self, data_entry): text = data_entry[self.text_key] - cleaned_string = self.pattern.sub("", text).strip() + cleaned_string = text + if self.pattern: + cleaned_string = self.pattern.sub("", cleaned_string).strip() cleaned_string = re.sub("\\s+", " ", cleaned_string).strip() words = cleaned_string.split() num_words = len(words) @@ -559,23 +429,28 @@ def finalize(self, metrics): class SubRegex(BaseParallelProcessor): - """Converts a regex match to a string, as defined by key-value pairs in ``regex_to_sub``. + """ + Applies a sequence of regex substitutions to the specified text field in each data entry. + + This processor performs regex-based substitutions as defined in either a provided list of + regex parameter dictionaries or a YAML configuration file. Each substitution is applied in + the order specified. - Before applying regex changes, we will add a space - character to the beginning and end of the ``text`` and ``pred_text`` - keys for each data entry. After the the regex changes, - the extra spaces are removed. This includes the spaces in the beginning - and end of the text, as well as any double spaces ``" "``. + Before substitutions are applied, a space is temporarily added to the beginning and end of the text + to improve regex match consistency. After all substitutions, leading/trailing spaces and repeated + spaces are removed. Args: - regex_params_list (list[dict]): list of dicts. - Each dict must contain a ``pattern`` and a ``repl`` key, - and optionally a ``count`` key (by default, ``count`` will be 0). - This processor will go through the list in order, and apply a ``re.sub`` operation on - the input text in ``data_entry[self.text_key]``, feeding in the specified ``pattern``, ``repl`` - and ``count`` parameters to ``re.sub``. - text_key (str): a string indicating which key of the data entries - should be used to find the utterance transcript. Defaults to "text". + regex_params_list (List[Dict], optional): A list of dictionaries specifying the regex substitutions. + Each dictionary must include: + - "pattern": A regex pattern to match. + - "repl": A replacement string. + - "count" (optional): Maximum number of replacements to make. Defaults to 0 (replace all). + regex_params_yaml (str, optional): Path to a YAML file that defines the same list of dictionaries + as `regex_params_list`. Either `regex_params_list` or `regex_params_yaml` must be provided. + If both are provided, `regex_params_yaml` takes precedence. + text_key (str): The key in each data entry whose value will be modified. Defaults to "text". + **kwargs: Additional arguments passed to the BaseParallelProcessor. Returns: The same data as in the input manifest with ```` field changed. @@ -583,12 +458,20 @@ class SubRegex(BaseParallelProcessor): def __init__( self, - regex_params_list: List[Dict], + regex_params_list: List[Dict] = None, + regex_params_yaml: str = None, text_key: str = "text", **kwargs, ): super().__init__(**kwargs) + if not regex_params_list and not regex_params_yaml: + raise ValueError(f'One of `regex_params_list` or `regex_params_yaml` should be provided.') + self.regex_params_list = regex_params_list + if regex_params_yaml: + with open(regex_params_yaml, 'r') as regex_params_file: + self.regex_params_list = yaml.safe_load(regex_params_file) + self.text_key = text_key # verify all dicts in regex_params_list have "pattern" and "repl" keys @@ -1127,3 +1010,371 @@ def process(self): if self.failed_files: logger.warning(f"Failed to process {len(self.failed_files)} files.") logger.debug(f"Failed files: {self.failed_files}") + + +class ListToEntries(BaseParallelProcessor): + """ + A dataset processor that transforms a single entry containing a list of items into multiple entries, + one for each item in the list. + + This is useful when a manifest field (e.g., "segments") contains a list of sub-entries, and you want + to flatten these into individual records for further processing. + + Args: + field_with_list (str): The name of the field in the input entry that contains a list. + output_field (str, optional): The name of the output field to assign to items in the list + if they are not dictionaries. Required if the list contains primitive types (e.g., strings). + fields_to_save (list[str], optional): A list of field names to preserve from the original entry. + All other fields will be removed. + fields_to_remove (list[str], optional): A list of field names to explicitly remove from the original entry, + in addition to those excluded by `fields_to_save`. + **kwargs: Additional arguments passed to the BaseParallelProcessor. + + Raises: + TypeError: If the specified list field is not of type list. + ValueError: If the list items are not dictionaries and `output_field` is not provided. + + Returns: + A manifest where each entry corresponds to one item in the original list from the input entry. + This effectively transforms a single input entry containing a list of items into multiple standalone + entries, each suitable for further dataset processing. + + .. admonition:: Example 1 (list of dicts) + + .. code-block:: yaml + + - _target_: sdp.processors.ListToEntries + input_manifest_file: ${workspace_dir}/input_manifest.json + output_manifest_file: ${workspace_dir}/output_manifest.json + field_with_list: "segments" + + Input:: + + { + "audio_filepath": "sample.wav", + "segments": [ + {"start": 0.0, "end": 1.5, "text": "Hello"}, + {"start": 1.6, "end": 3.0, "text": "World"} + ] + } + + Output:: + + [ + { + "audio_filepath": "sample.wav", + "start": 0.0, + "end": 1.5, + "text": "Hello" + }, + { + "audio_filepath": "sample.wav", + "start": 1.6, + "end": 3.0, + "text": "World" + } + ] + + .. admonition:: Example 2 (list of primitives) + + .. code-block:: yaml + + - _target_: sdp.processors.ListToEntries + input_manifest_file: ${workspace_dir}/input_manifest.json + output_manifest_file: ${workspace_dir}/output_manifest.json + field_with_list: "text_chunks" + output_field: "text" + + Input:: + + { + "audio_filepath": "sample.wav", + "text_chunks": [ + "Hello", + "World" + ] + } + + Output:: + + [ + { + "audio_filepath": "sample.wav", + "text": "Hello" + }, + { + "audio_filepath": "sample.wav", + "text": "World" + } + ] + + """ + + def __init__(self, + field_with_list: str, + output_field: str = None, + fields_to_save: list[str] = None, + fields_to_remove: list[str] = None, + **kwargs): + super().__init__(**kwargs) + self.field_with_list = field_with_list + self.output_field = output_field + self.fields_to_save = fields_to_save + self.fields_to_remove = fields_to_remove + + def process_dataset_entry(self, data_entry): + _entries = [] + + # Check that the target field is actually a list + if not isinstance(data_entry[self.field_with_list], list): + raise TypeError(f'Values of {self.field_with_list} field should be list type only: {data_entry}') + + # Remove the list field from the entry and get the list of items + items_list = data_entry.pop(self.field_with_list) + + # If items are not dicts, output_field must be specified to store the item + if not isinstance(items_list[0], dict) and not self.output_field: + raise ValueError(f'Type of items in items list `{self.field_with_list}` is not dict ({type(items_list[0])}). In this case `output_field` should be provided.') + + # Determine which fields to remove from the entry before expanding + fields_to_remove = set() + if self.fields_to_save is not None: + for field in data_entry: + if field not in self.fields_to_save: + fields_to_remove.add(field) + + if self.fields_to_remove is not None: + fields_to_remove.update(self.fields_to_remove) + + # Remove specified fields + for field in fields_to_remove: + data_entry.pop(field) + + # Expand the list into multiple entries + for item in items_list: + _entry = data_entry.copy() + + # If item is a dict, merge its keys; otherwise, store it in `output_field` + if isinstance(item, dict): + _entry.update(item) + else: + _entry[self.output_field] = item + + _entry = DataEntry(_entry) + _entries.append(_entry) + + return _entries + + +class LambdaExpression(BaseParallelProcessor): + """ + A dataset processor that evaluates a Python expression on each data entry and either stores + the result in a new field or uses it as a filtering condition. + + This processor is useful for dynamic field computation or conditional filtering of entries based + on configurable expressions. It leverages `evaluate_expression`, which safely evaluates expressions + using the abstract syntax tree (AST). + + Args: + new_field (str): The name of the field to store the result of the expression. + expression (str): A Python expression to evaluate. It can reference fields of the data entry + using the name specified by `lambda_param_name`. + lambda_param_name (str, optional): The name to refer to the current data entry in the expression. + Default is "entry". + filter (bool, optional): If True, the expression result is treated as a condition. + The entry is kept only if the result is `True`. Default is False. + **kwargs: Additional keyword arguments passed to the BaseParallelProcessor class. + + Returns: + A line-delimited JSON manifest, where each line is a processed entry. + The result may contain fewer entries than the input if `filter=True`. + """ + def __init__( + self, + new_field: str, + expression: str, + lambda_param_name: str = "entry", + filter: bool = False, + **kwargs, + ): + super().__init__(**kwargs) + self.new_field = new_field + self.expression = expression + self.lambda_param_name = lambda_param_name + self.filter = filter + + def process_dataset_entry(self, data_entry) -> List[DataEntry]: + """ + Process a single data entry by evaluating the expression. + + If `filter` is True, the entry is only retained if the expression evaluates to True. + Otherwise, the result is stored in `new_field`. + """ + value = evaluate_expression(self.expression, data_entry, self.lambda_param_name) + if self.filter: + if value is not True: + return [] + data_entry[self.new_field] = value + return [DataEntry(data=data_entry)] + + def finalize(self, metrics): + super().finalize(metrics) + + +class FilterWithCharacterHistograms(BaseParallelProcessor): + """ + A processor that filters text based on character histogram similarity to trusted data in the target language. + + This processor computes the ratio of characters in a given text that are found in a reference character histogram + for a specific language. If this ratio is below a certain threshold, the text is likely mislabeled or noisy. + + Histograms are sourced from the NLLB paper (https://arxiv.org/pdf/2207.04672), see page 30 for methodology. This + technique is a lightweight language ID filter, designed to catch mismatches between text content and claimed language. + + Reference implementation: https://github.com/facebookresearch/fairseq/blob/main/examples/m2m_100/process_data/clean_histogram.py + + Args: + text_field (str): Key in the data entry containing the text to evaluate. + lang_field (str, optional): Key in the data entry that identifies the language. Required if `lang` is not provided. + lang (str, optional): Language code to use for all entries (overrides `lang_field`). Required if `lang_field` is not provided. + threshold (float): Threshold ratio to determine if text matches the histogram. Used only externally (not enforced in this processor). + cache_dir (str, optional): Directory where histograms are downloaded and cached. + threshold_char (str): Character used to truncate the histogram file (default is ']'). + output_score_field (str): Key name under which the computed character match ratio will be stored. + **kwargs: Additional keyword arguments passed to `BaseParallelProcessor`. + + Raises: + ValueError: If both `lang` and `lang_field` are provided, or if neither is provided. + Also raised if histogram for specified language is missing. + + Returns: + A manifest where each entry includes the additional field `output_score_field` with the character match ratio. + Example:: + + { + "text": "hello world", + "lang": "en", + "hist_token_ratio": 0.95 + } + """ + + HISTOGRAMS_URL = 'https://dl.fbaipublicfiles.com/m2m_100/histograms.tar.gz' + + def __init__(self, + text_field: str, + lang_field: str = None, + lang: str = None, + threshold: float = 0.8, + cache_dir: str = None, + threshold_char: str = "]", + output_score_field: str = "hist_token_ratio", + **kwargs): + super().__init__(**kwargs) + self.text_field = text_field + + # Ensure exactly one of `lang` or `lang_field` is provided + if lang_field is None and lang is None: + raise ValueError("One of the arguments `lang` or `lang_field` must be provided.") + if lang_field is not None and lang is not None: + raise ValueError( + f"Both `lang` ({lang}) and `lang_field` ({lang_field}) are provided, which makes the source of language ambiguous. Please provide only one of them." + ) + + self.lang_field = lang_field + self.lang = lang + self.threshold = threshold + self.cache_dir = cache_dir + self.threshold_char = threshold_char + self.output_score_field = output_score_field + self.histograms = dict() + + def _read_hist(self, lang: str): + """ + Read and parse the histogram file for a given language, stopping at the threshold character. + """ + hist_file = os.path.join(self.cache_dir, lang) + chars = [] + with open(hist_file) as hist: + for line in hist: + char = line[0] + chars.append(char) + if char == self.threshold_char: + break + self.histograms[lang] = set(chars) + + def _download_histograms(self): + """ + Download and extract histogram files into the cache directory. + """ + logger.info('Downloading histograms collection..') + response = requests.get(self.HISTOGRAMS_URL) + if response.status_code != 200: + raise requests.exceptions.RequestException( + f"Failed to download model file. Status code: {response.status_code}" + ) + + if self.cache_dir is None: + self.cache_dir = tempfile.mkdtemp() + + os.makedirs(self.cache_dir, exist_ok=True) + + histograms_tarfile = wget.download(self.HISTOGRAMS_URL, out=self.cache_dir) + with tarfile.open(histograms_tarfile, "r:gz") as tar: + tar.extractall(path=self.cache_dir) + + # Flatten subdirectories into the main cache_dir + histograms_filepaths = glob(f'{self.cache_dir}/checkpoint/edunov/cc60_multilingual/clean_hists/*') + for histogram_filepath in histograms_filepaths: + shutil.move(histogram_filepath, os.path.join(self.cache_dir, os.path.basename(histogram_filepath))) + + os.remove(histograms_tarfile) + shutil.rmtree(f'{self.cache_dir}/checkpoint/edunov/cc60_multilingual/clean_hists/') + logger.info(f'Histograms have been downloaded to {self.cache_dir}.') + + def prepare(self): + """ + Ensure histograms are available and read them into memory. + """ + if (self.cache_dir is None or + not os.path.exists(self.cache_dir) or + not os.path.isdir(self.cache_dir) or + len(os.listdir(self.cache_dir)) == 0): + + self._download_histograms() + + logger.info('Reading histograms...') + available_langs = os.listdir(self.cache_dir) + if self.lang is not None: + if self.lang in available_langs: + self._read_hist(self.lang) + else: + raise ValueError(f"Invalid value for `lang`: {self.lang}. Please provide one of the following: {available_langs}") + logger.info(f'Histogram for `{self.lang}` has been read.') + else: + for lang in tqdm(available_langs): + self._read_hist(lang) + logger.info(f'Histograms have been read.') + + def process_dataset_entry(self, data_entry): + """ + Compute and attach the character histogram match ratio for a given text entry. + + Args: + data_entry (dict): A dictionary containing at least `text_field` and either `lang_field` or a preset `lang`. + + Returns: + List[DataEntry]: A list with one updated `DataEntry` including the character match ratio field. + """ + # Determine language for this entry + lang = self.lang if self.lang is not None else data_entry[self.lang_field] + if lang not in self.histograms: + raise ValueError(f'lang `{lang}` is not supported.') + + # Compute how many characters match the histogram + text = data_entry[self.text_field].strip() + cnt = len([c for c in text if c in self.histograms[lang]]) + token_ratio = cnt / len(text) if len(text) > 0 else 0.0 + + # Store the ratio in the data entry + data_entry[self.output_score_field] = token_ratio + return [DataEntry(data=data_entry)] diff --git a/sdp/processors/nemo/__init__.py b/sdp/processors/nemo/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/sdp/utils/apply_operators.py b/sdp/utils/apply_operators.py new file mode 100644 index 00000000..7bb5975d --- /dev/null +++ b/sdp/utils/apply_operators.py @@ -0,0 +1,154 @@ +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import operator +import ast +import re +from typing import Any, Dict + +""" +This module provides a safe evaluator for simple Python expressions using the abstract syntax tree (AST). +It restricts execution to a subset of safe operations (arithmetic, logical, comparisons, indexing, etc.) +and selected built-in functions (e.g., max, min, len), while preventing arbitrary code execution. + +Useful in cases where dynamic expressions need to be evaluated using a provided variable context, +such as configuration systems, data transformation pipelines, or manifest filtering. + +Functions: + - evaluate_expression: Safely evaluates a Python expression string using restricted AST operations. +""" + +OPERATORS = { + ast.Add: operator.add, # Addition (a + b) + ast.Sub: operator.sub, # Subtraction (a - b) + ast.Mult: operator.mul, # Multiplication (a * b) + ast.Div: operator.truediv, # True Division (a / b) + ast.FloorDiv: operator.floordiv, # Floor Division (a // b) + ast.Mod: operator.mod, # Modulus (a % b) + ast.Pow: operator.pow, # Exponentiation (a ** b) + ast.BitOr: operator.or_, # Bitwise OR (a | b) + ast.BitAnd: operator.and_, # Bitwise AND (a & b) + ast.BitXor: operator.xor, # Bitwise XOR (a ^ b) + ast.LShift: operator.lshift, # Left Shift (a << b) + ast.RShift: operator.rshift, # Right Shift (a >> b) + ast.Invert: operator.invert, # Bitwise NOT (~a) + ast.USub: operator.neg, # Negation (-a) + ast.UAdd: operator.pos, # Unary Plus (+a) + ast.Eq: operator.eq, # Equality Check (a == b) + ast.NotEq: operator.ne, # Inequality Check (a != b) + ast.Lt: operator.lt, # Less Than (a < b) + ast.LtE: operator.le, # Less Than or Equal To (a <= b) + ast.Gt: operator.gt, # Greater Than (a > b) + ast.GtE: operator.ge, # Greater Than or Equal To (a >= b) + ast.Is: operator.is_, # Identity Check (a is b) + ast.IsNot: operator.is_not, # Negated Identity Check (a is not b) + ast.And: operator.and_, # Logical AND (a and b) + ast.Or: operator.or_, # Logical OR (a or b) + ast.Not: operator.not_, # Logical NOT (not a) +} + +SAFE_FUNCTIONS = { + 'max': max, + 'min': min, + 'len': len, + 'sum': sum, + 'abs': abs, + 'sorted': sorted, +} + +def evaluate_expression(expression: str, variables: Dict[str, Any] = None, var_prefix: str = None) -> any: + """ + Safely evaluates a Python expression string using a restricted set of AST nodes and operators. + + This function supports arithmetic operations, comparisons, logical expressions, list/dict indexing, + conditional expressions, and a whitelist of safe built-in functions. It allows evaluating expressions + in the context of a user-provided dictionary of variables. + + Args: + expression (str): The expression to evaluate. Example: "x + 2 if y > 3 else 0". + variables (Dict[str, Any], optional): A dictionary of variable names and values to use in evaluation. + var_prefix (str, optional): If specified, this prefix will be removed from variable names + in the expression before evaluation (e.g., "data.x" → "x"). + + Returns: + any: The result of evaluating the expression. + + Raises: + ValueError: If the expression contains unsupported operations or names. + """ + + if variables is None: + variables = {} + + def _eval(node): + if isinstance(node, ast.Expression): + return _eval(node.body) + elif isinstance(node, ast.BinOp): # Binary operations + left = _eval(node.left) + right = _eval(node.right) + return OPERATORS[type(node.op)](left, right) + elif isinstance(node, ast.UnaryOp): # Unary operations + operand = _eval(node.operand) + return OPERATORS[type(node.op)](operand) + elif isinstance(node, ast.Subscript): # Accessing elements with [] + value = _eval(node.value) # The collection (e.g., list, dict) + if isinstance(node.slice, ast.Slice): # Slice processing + start = _eval(node.slice.lower) if node.slice.lower else None + stop = _eval(node.slice.upper) if node.slice.upper else None + step = _eval(node.slice.step) if node.slice.step else None + return value[start:stop:step] + else: + key = _eval(node.slice) # The index/key + return value[key] + elif isinstance(node, ast.Compare): # Comparisons + left = _eval(node.left) + right = _eval(node.comparators[0]) + return OPERATORS[type(node.ops[0])](left, right) + elif isinstance(node, ast.BoolOp): # Logical operations + values = [_eval(value) for value in node.values] + if isinstance(node.op, ast.And): + return all(values) + elif isinstance(node.op, ast.Or): + return any(values) + elif isinstance(node, ast.IfExp): # Ternary if (condition ? true_value : false_value) + test = _eval(node.test) + return _eval(node.body) if test else _eval(node.orelse) + elif isinstance(node, ast.Constant): # Numbers, strings, etc. + return node.value + elif isinstance(node, ast.NameConstant): # True, False, None + return node.value + elif isinstance(node, ast.Name): # For identifiers + var_name = node.id + if var_name in variables: # Look for variables in the provided dictionary + return variables[var_name] + elif var_name in {"True", "False"}: + return eval(var_name) + raise ValueError(f"Unsupported name: {node.id}") + elif isinstance(node, ast.Call): # Function call handling + func_name = node.func.id if isinstance(node.func, ast.Name) else None + if func_name in SAFE_FUNCTIONS: + func = SAFE_FUNCTIONS[func_name] + args = [_eval(arg) for arg in node.args] + return func(*args) + else: + raise ValueError(f"Function {func_name} is not allowed") + else: + raise ValueError(f"Unsupported node type: {type(node)}") + + var_prefix += '.' + expression = re.sub(rf'{re.escape(var_prefix)}(\w+)', r'\1', expression) + + # Parse the expression into an AST tree + tree = ast.parse(expression, mode='eval') + return _eval(tree.body) \ No newline at end of file diff --git a/tests/prepare_test_data/prepare_yodas2_data.py b/tests/prepare_test_data/prepare_yodas2_data.py new file mode 100644 index 00000000..ef37f191 --- /dev/null +++ b/tests/prepare_test_data/prepare_yodas2_data.py @@ -0,0 +1,156 @@ +# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Script to download and prepare a specific shard of the YODAS2 dataset for testing or development purposes. + +Main features: +- Downloads audio, duration, and text files for a given language subset and shard from Hugging Face (`espnet/yodas2`). +- Uses `huggingface_hub.snapshot_download` if available; otherwise falls back to direct `wget` download. +- Supports trimming the dataset to only the first N entries via the `--num_entries` flag. +- Repackages selected audio entries into a new `.tar.gz`. +- Generates a minimal manifest JSON with references to the downloaded local files. +""" + +import argparse +import os +import json +from pathlib import Path +import tempfile +import shutil +import tarfile +import io +from huggingface_hub import hf_hub_download + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Prepare a specific YODAS2 test data shard for local use.") + + parser.add_argument( + "--lang_subset", + default="en000", + help=( + "Language and subset ID from the YODAS2 dataset (e.g., 'en000', 'de003'). " + "Used to construct the remote path: data//..." + ), + ) + + parser.add_argument( + "--shard_id", + default="00000000", + help=( + "Shard ID to download (e.g., '00000000'). " + "Used as a filename to identify the .tar.gz, .txt, and .json files." + ), + ) + + parser.add_argument( + "--num_entries", + default=-1, + type=int, + help=( + "If set to a positive integer, only the first N entries will be extracted " + "from the shard (including audio, duration, and text). Use -1 to keep all data." + ), + ) + + parser.add_argument( + "--test_data_folder", + required=True, + help="Target directory where files and manifest will be saved.", + ) + + args = parser.parse_args() + + # Resolve target output directory and ensure it exists + test_data_folder = Path(args.test_data_folder).resolve() + os.makedirs(test_data_folder, exist_ok=True) + + # File keys used to construct Hugging Face paths + shard = dict( + audio = dict(key = f"data/{args.lang_subset}/audio/{args.shard_id}.tar.gz"), + duration = dict(key = f"data/{args.lang_subset}/duration/{args.shard_id}.txt"), + text = dict(key = f"data/{args.lang_subset}/text/{args.shard_id}.json") + ) + + # Temporary directory for downloads + with tempfile.TemporaryDirectory() as tmpdir: + for datatype in shard: + tmp_filepath = hf_hub_download( + repo_id="espnet/yodas2", + repo_type="dataset", + filename = shard[datatype]['key'], + local_dir=tmpdir, + local_dir_use_symlinks = False, + ) + + assert os.path.exists(tmp_filepath), f"{datatype} file missing after download ({tmp_filepath} not found)." + shard[datatype]['src_filepath'] = tmp_filepath + + dest_filepath = os.path.join(test_data_folder, shard[datatype]['key']) + shard[datatype]['dest_filepath'] = dest_filepath + os.makedirs(os.path.dirname(dest_filepath), exist_ok=True) + + if args.num_entries == -1: + shutil.move(tmp_filepath, dest_filepath) + + if args.num_entries != -1: + yodas_ids = [] + with open(shard['duration']['src_filepath'], 'r') as fin, open(shard['duration']['dest_filepath'], 'w') as fout: + for i, line in enumerate(fin, 1): + yodas_id = line.split()[0] + yodas_ids.append(yodas_id) + fout.write(line) + if i >= args.num_entries: + break + else: + print(f"Warning: fewer lines than requested ({args.num_entries}).") + + with open(shard['text']['src_filepath'], 'r', encoding='utf8') as fin, open(shard['text']['dest_filepath'], 'w', encoding='utf8') as fout: + all_samples = json.load(fin) + selected = [s for s in all_samples if s['audio_id'] in yodas_ids] + + if len(selected) != len(yodas_ids): + raise ValueError("Mismatch between duration and text entries.") + + fout.write(json.dumps(selected) + '\n') + + # Extract and repack audio subset + with tarfile.open(shard['audio']['src_filepath'], "r:gz") as tar_in, tarfile.open(shard['audio']['dest_filepath'], "w:gz") as tar_out: + for yodas_id in yodas_ids: + filename = f"./{yodas_id}.wav" + member = tar_in.getmember(filename) + audio_bytes = tar_in.extractfile(member).read() + file_obj = io.BytesIO(audio_bytes) + member.size = len(audio_bytes) + tar_out.addfile(member, fileobj=file_obj) + + # Determine manifest location and folder + lang = args.lang_subset[:2] + manifest_dir = os.path.join(test_data_folder, lang) + os.makedirs(manifest_dir, exist_ok=True) + + manifest_path = os.path.join(manifest_dir, "manifest_03.json") + with open(manifest_path, 'w', encoding='utf8') as manifest: + sample = { + "lang_subset": args.lang_subset, + "shard_id": args.shard_id, + "audio_key": shard['audio']['key'], + "duration_key": shard['duration']['key'], + "text_key": shard['text']['key'], + "src_lang": lang, + "local_audio": shard['audio']['dest_filepath'], + "local_duration": shard['duration']['dest_filepath'], + "local_text": shard['text']['dest_filepath'], + } + manifest.write(json.dumps(sample) + '\n') \ No newline at end of file diff --git a/tests/test_cfg_runtime_tests.py b/tests/test_cfg_runtime_tests.py index cce1b820..73f32cad 100644 --- a/tests/test_cfg_runtime_tests.py +++ b/tests/test_cfg_runtime_tests.py @@ -25,7 +25,11 @@ def get_test_cases(): """Returns paths to all configs that are checked in.""" for config_path in glob.glob(f"{DATASET_CONFIGS_ROOT}/**/*.yaml", recursive=True): - yield config_path + path_parts = Path(config_path).parts + if "partials" in path_parts: + continue + else: + yield config_path @pytest.mark.parametrize("config_path", get_test_cases()) diff --git a/tests/test_data_to_data.py b/tests/test_data_to_data.py index 5bd75f47..1e006149 100644 --- a/tests/test_data_to_data.py +++ b/tests/test_data_to_data.py @@ -19,8 +19,12 @@ SubIfASRSubstitution, SubMakeLowercase, SubRegex, + ListToEntries, + LambdaExpression, ) +from sdp.processors.inference.llm.post_processing.qwen_cleaning import CleanQwenGeneration + test_params_list = [] test_params_list.extend( @@ -29,13 +33,13 @@ InsIfASRInsertion, {"insert_words": [" nemo", "nemo ", " nemo "]}, {"text": "i love the toolkit", "pred_text": "i love the nemo toolkit"}, - {"text": "i love the nemo toolkit", "pred_text": "i love the nemo toolkit"}, + [{"text": "i love the nemo toolkit", "pred_text": "i love the nemo toolkit"}], ), ( InsIfASRInsertion, {"insert_words": [" nemo", "nemo ", " nemo "]}, {"text": "i love the toolkit", "pred_text": "i love the new nemo toolkit"}, - {"text": "i love the toolkit", "pred_text": "i love the new nemo toolkit"}, + [{"text": "i love the toolkit", "pred_text": "i love the new nemo toolkit"}], ), ] ) @@ -46,7 +50,7 @@ SubIfASRSubstitution, {"sub_words": {"nmo ": "nemo "}}, {"text": "i love the nmo toolkit", "pred_text": "i love the nemo toolkit"}, - {"text": "i love the nemo toolkit", "pred_text": "i love the nemo toolkit"}, + [{"text": "i love the nemo toolkit", "pred_text": "i love the nemo toolkit"}], ), ] ) @@ -57,7 +61,7 @@ SubIfASRSubstitution, {"sub_words": {"nmo ": "nemo "}}, {"text": "i love the nmo toolkit", "pred_text": "i love the nemo toolkit"}, - {"text": "i love the nemo toolkit", "pred_text": "i love the nemo toolkit"}, + [{"text": "i love the nemo toolkit", "pred_text": "i love the nemo toolkit"}], ), ] ) @@ -68,13 +72,13 @@ SubMakeLowercase, {}, {"text": "Hello Привет 123"}, - {"text": "hello привет 123"}, + [{"text": "hello привет 123"}], ), ( SubMakeLowercase, {"text_key": "text_new"}, {"text_new": "Hello Привет 123"}, - {"text_new": "hello привет 123"}, + [{"text_new": "hello привет 123"}], ), ] ) @@ -85,16 +89,178 @@ SubRegex, {"regex_params_list": [{"pattern": "\s<.*>\s", "repl": " "}]}, {"text": "hello world"}, + [{"text": "hello world"}], + ), + ] +) + +test_params_list.extend( + [ + # Test: list of dictionaries (e.g., segments) + ( + ListToEntries, + {"field_with_list": "segments", "fields_to_remove": ["duration"]}, + {"audio_filepath": "a.wav", "segments": [{"start": 0.0, "end": 1.0, "text": "Hello"}, {"start": 1.1, "end": 2.0, "text": "World"}], "duration": 2.5}, + [{"audio_filepath": "a.wav", "start": 0.0, "end": 1.0, "text": "Hello"}, {"audio_filepath": "a.wav", "start": 1.1, "end": 2.0, "text": "World"}] + ), + # Test: list of primitive values (strings), requires output_field + ( + ListToEntries, + {"field_with_list": "text_chunks", "output_field": "text"}, + {"audio_filepath": "b.wav", "text_chunks": ["Привет", "Мир"], "lang": "ru"}, + [{"audio_filepath": "b.wav", "lang": "ru", "text": "Привет"}, {"audio_filepath": "b.wav", "lang": "ru", "text": "Мир"}] + ), + # Test: only keep specified fields (fields_to_save) + ( + ListToEntries, + {"field_with_list": "segments", "fields_to_save": ["audio_filepath"]}, + {"audio_filepath": "c.wav", "segments": [{"start": 0, "text": "A"}, {"start": 1, "text": "B"}], "remove_me": "to_delete"}, + [{"audio_filepath": "c.wav", "start": 0, "text": "A"}, {"audio_filepath": "c.wav", "start": 1, "text": "B"}] + ) + ] +) + +test_params_list.extend( + [ + # Simple arithmetic expression + ( + LambdaExpression, + {"new_field": "duration_x2", "expression": "entry.duration * 2"}, + {"duration": 3.5}, + [{"duration": 3.5, "duration_x2": 7.0}], + ), + + # Ternary expression + ( + LambdaExpression, + {"new_field": "label", "expression": "'long' if entry.duration > 10 else 'short'"}, + {"duration": 12.0}, + [{"duration": 12.0, "label": "long"}], + ), + + # Filtering: entry should be dropped (condition is False) + ( + LambdaExpression, + {"new_field": "valid", "expression": "entry.duration > 10", "filter": True}, + {"duration": 5.0}, + [], + ), + + # Filtering: entry should be kept (condition is True) + ( + LambdaExpression, + {"new_field": "valid", "expression": "entry.duration > 10", "filter": True}, + {"duration": 12.0}, + [{"duration": 12.0, "valid": True}], + ), + + # Using built-in function len() + ( + LambdaExpression, + {"new_field": "num_chars", "expression": "len(entry.text)"}, {"text": "hello world"}, + [{"text": "hello world", "num_chars": 11}], + ), + + # Using built-in max() with sub-expressions + ( + LambdaExpression, + {"new_field": "score", "expression": "max(entry.a, entry.b * 2)"}, + {"a": 4, "b": 3}, + [{"a": 4, "b": 3, "score": 6}], + ), + + # Expression using variable prefix (e.g., entry.a + entry.b) + ( + LambdaExpression, + { + "new_field": "sum", + "expression": "entry.a + entry.b", + "lambda_param_name": "entry", + }, + {"a": 1, "b": 2}, + [{"a": 1, "b": 2, "sum": 3}], + ), + + # Logical expression using `and` + ( + LambdaExpression, + { + "new_field": "check", + "expression": "entry.a > 0 and entry.b < 5", + }, + {"a": 1, "b": 4}, + [{"a": 1, "b": 4, "check": True}], + ), + + # Boolean expression without filtering (entry is always returned) + ( + LambdaExpression, + { + "new_field": "is_zero", + "expression": "entry.value == 0", + }, + {"value": 5}, + [{"value": 5, "is_zero": False}], ), ] ) +test_params_list.extend( + [ + # Case: generation is fine, no replacement + ( + CleanQwenGeneration, + {"cer_threshold": 10, "upper_case_threshold": 0.6}, + {"text": "hello world", "generation": "hello world"}, + [{"text": "hello world", "generation": "hello world"}], + ), + + # Case: generation is completely uppercase → replaced + ( + CleanQwenGeneration, + {"cer_threshold": 10, "upper_case_threshold": 0.5}, + {"text": "hello world", "generation": "HELLO WORLD"}, + [{"text": "hello world", "generation": "hello world"}], + ), + + # Case: generation contains <|endoftext|> and prompt remnants → cleaned + ( + CleanQwenGeneration, + {}, + {"text": "hello", "generation": "Input transcript: hello\nOutput transcript: hello<|endoftext|>"}, + [{"text": "hello", "generation": "hello"}], + ), + + # Case: generation is too different → high CER → replaced + ( + CleanQwenGeneration, + {"cer_threshold": 0.2}, + {"text": "hello world", "generation": "xyz abc"}, + [{"text": "hello world", "generation": "hello world"}], + ), + + # Case: generation is empty → replaced + ( + CleanQwenGeneration, + {}, + {"text": "reference", "generation": ""}, + [{"text": "reference", "generation": "reference"}], + ), + + # Case: text is empty → fallback to replacement + ( + CleanQwenGeneration, + {}, + {"text": "", "generation": "some output"}, + [{"text": "", "generation": ""}], + ), + ] +) @pytest.mark.parametrize("test_class,class_kwargs,test_input,expected_output", test_params_list, ids=str) def test_data_to_data(test_class, class_kwargs, test_input, expected_output): processor = test_class(**class_kwargs, output_manifest_file=None) + result = [entry.data for entry in processor.process_dataset_entry(test_input)] - output = processor.process_dataset_entry(test_input)[0].data - - assert output == expected_output + assert result == expected_output diff --git a/tests/test_modify_manifest.py b/tests/test_modify_manifest.py index 99583c26..1cbe35b4 100644 --- a/tests/test_modify_manifest.py +++ b/tests/test_modify_manifest.py @@ -19,7 +19,7 @@ import pytest -from sdp.processors import ApplyInnerJoin, DropNonAlphabet +from sdp.processors import JoinManifests, DropNonAlphabet def _write_manifest(manifest: Path, entries: List[Dict[str, Union[str, float]]]): @@ -157,7 +157,7 @@ def test_apply_inner_join( processor = ApplyInnerJoin( left_manifest_file=manifest1, right_manifest_file=manifest2, - column_id=coloumn_id, + merge_params=dict(on = coloumn_id, how = 'inner'), output_manifest_file=manifest_out, )