| New file |
| | |
| | | # TIMESTAMP PREDICTION |
| | | |
| | | ## Inference |
| | | |
| | | ### Quick start |
| | | #### [Use TP-Aligner Model Simply](https://modelscope.cn/models/damo/speech_timestamp_prediction-v1-16k-offline/summary) |
| | | ```python |
| | | from modelscope.pipelines import pipeline |
| | | from modelscope.utils.constant import Tasks |
| | | |
| | | inference_pipline = pipeline( |
| | | task=Tasks.speech_timestamp, |
| | | model='damo/speech_timestamp_prediction-v1-16k-offline', |
| | | output_dir=None) |
| | | |
| | | rec_result = inference_pipline( |
| | | audio_in='https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/asr_example_timestamps.wav', |
| | | text_in='一 个 东 太 平 洋 国 家 为 什 么 跑 到 西 太 平 洋 来 了 呢',) |
| | | print(rec_result) |
| | | ``` |
| | | |
| | | Timestamp pipeline can also be used after ASR pipeline to compose complete ASR function, ref to [demo](https://github.com/alibaba-damo-academy/FunASR/discussions/246). |
| | | |
| | | |
| | | |
| | | #### API-reference |
| | | ##### Define pipeline |
| | | - `task`: `Tasks.speech_timestamp` |
| | | - `model`: model name in [model zoo](https://alibaba-damo-academy.github.io/FunASR/en/modelscope_models.html#pretrained-models-on-modelscope), or model path in local disk |
| | | - `ngpu`: `1` (Default), decoding on GPU. If ngpu=0, decoding on CPU |
| | | - `ncpu`: `1` (Default), sets the number of threads used for intraop parallelism on CPU |
| | | - `output_dir`: `None` (Default), the output path of results if set |
| | | - `batch_size`: `1` (Default), batch size when decoding |
| | | ##### Infer pipeline |
| | | - `audio_in`: the input speech to predict, which could be: |
| | | - wav_path, `e.g.`: asr_example.wav (wav in local or url), |
| | | - wav.scp, kaldi style wav list (`wav_id wav_path`), `e.g.`: |
| | | ```text |
| | | asr_example1 ./audios/asr_example1.wav |
| | | asr_example2 ./audios/asr_example2.wav |
| | | ``` |
| | | In this case of `wav.scp` input, `output_dir` must be set to save the output results |
| | | - `text_in`: the input text to predict, splited by blank, which could be: |
| | | - text string, `e.g.`: `今 天 天 气 怎 么 样` |
| | | - text.scp, kaldi style text file (`wav_id transcription`), `e.g.`: |
| | | ```text |
| | | asr_example1 今 天 天 气 怎 么 样 |
| | | asr_example2 欢 迎 体 验 达 摩 院 语 音 识 别 模 型 |
| | | ``` |
| | | - `audio_fs`: audio sampling rate, only set when audio_in is pcm audio |
| | | - `output_dir`: None (Default), the output path of results if set, containing |
| | | - output_dir/timestamp_prediction/tp_sync, timestamp in second containing silence periods, `wav_id# token1 start_time end_time;`, `e.g.`: |
| | | ```text |
| | | test_wav1# <sil> 0.000 0.500;温 0.500 0.680;州 0.680 0.840;化 0.840 1.040;工 1.040 1.280;仓 1.280 1.520;<sil> 1.520 1.680;库 1.680 1.920;<sil> 1.920 2.160;起 2.160 2.380;火 2.380 2.580;殃 2.580 2.760;及 2.760 2.920;附 2.920 3.100;近 3.100 3.340;<sil> 3.340 3.400;河 3.400 3.640;<sil> 3.640 3.700;流 3.700 3.940;<sil> 3.940 4.240;大 4.240 4.400;量 4.400 4.520;死 4.520 4.680;鱼 4.680 4.920;<sil> 4.920 4.940;漂 4.940 5.120;浮 5.120 5.300;河 5.300 5.500;面 5.500 5.900;<sil> 5.900 6.240; |
| | | ``` |
| | | - output_dir/timestamp_prediction/tp_time, timestamp list in ms of same length as input text without silence `wav_id# [[start_time, end_time],]`, `e.g.`: |
| | | ```text |
| | | test_wav1# [[500, 680], [680, 840], [840, 1040], [1040, 1280], [1280, 1520], [1680, 1920], [2160, 2380], [2380, 2580], [2580, 2760], [2760, 2920], [2920, 3100], [3100, 3340], [3400, 3640], [3700, 3940], [4240, 4400], [4400, 4520], [4520, 4680], [4680, 4920], [4940, 5120], [5120, 5300], [5300, 5500], [5500, 5900]] |
| | | ``` |
| | | |
| | | ### Inference with multi-thread CPUs or multi GPUs |
| | | FunASR also offer recipes [egs_modelscope/vad/TEMPLATE/infer.sh](https://github.com/alibaba-damo-academy/FunASR/blob/main/egs_modelscope/vad/TEMPLATE/infer.sh) to decode with multi-thread CPUs, or multi GPUs. |
| | | |
| | | - Setting parameters in `infer.sh` |
| | | - `model`: model name in [model zoo](https://alibaba-damo-academy.github.io/FunASR/en/modelscope_models.html#pretrained-models-on-modelscope), or model path in local disk |
| | | - `data_dir`: the dataset dir **must** include `wav.scp` and `text.scp` |
| | | - `output_dir`: output dir of the recognition results |
| | | - `batch_size`: `64` (Default), batch size of inference on gpu |
| | | - `gpu_inference`: `true` (Default), whether to perform gpu decoding, set false for CPU inference |
| | | - `gpuid_list`: `0,1` (Default), which gpu_ids are used to infer |
| | | - `njob`: only used for CPU inference (`gpu_inference`=`false`), `64` (Default), the number of jobs for CPU decoding |
| | | - `checkpoint_dir`: only used for infer finetuned models, the path dir of finetuned models |
| | | - `checkpoint_name`: only used for infer finetuned models, `valid.cer_ctc.ave.pb` (Default), which checkpoint is used to infer |
| | | |
| | | - Decode with multi GPUs: |
| | | ```shell |
| | | bash infer.sh \ |
| | | --model "damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-pytorch" \ |
| | | --data_dir "./data/test" \ |
| | | --output_dir "./results" \ |
| | | --batch_size 64 \ |
| | | --gpu_inference true \ |
| | | --gpuid_list "0,1" |
| | | ``` |
| | | - Decode with multi-thread CPUs: |
| | | ```shell |
| | | bash infer.sh \ |
| | | --model "damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-pytorch" \ |
| | | --data_dir "./data/test" \ |
| | | --output_dir "./results" \ |
| | | --gpu_inference false \ |
| | | --njob 64 |
| | | ``` |
| | | |
| | | ## Finetune with pipeline |
| | | |
| | | ### Quick start |
| | | |
| | | ### Finetune with your data |
| | | |
| | | ## Inference with your finetuned model |
| | | |
| New file |
| | |
| | | ../speech_timestamp_prediction-v1-16k-offline/infer.py |
| New file |
| | |
| | | #!/usr/bin/env bash |
| | | |
| | | set -e |
| | | set -u |
| | | set -o pipefail |
| | | |
| | | stage=1 |
| | | stop_stage=2 |
| | | model="damo/speech_timestamp_prediction-v1-16k-offline" |
| | | data_dir="./data/test" |
| | | output_dir="./results" |
| | | batch_size=1 |
| | | gpu_inference=true # whether to perform gpu decoding |
| | | gpuid_list="0,1" # set gpus, e.g., gpuid_list="0,1" |
| | | njob=4 # the number of jobs for CPU decoding, if gpu_inference=false, use CPU decoding, please set njob |
| | | checkpoint_dir= |
| | | checkpoint_name="valid.cer_ctc.ave.pb" |
| | | |
| | | . utils/parse_options.sh || exit 1; |
| | | |
| | | if ${gpu_inference} == "true"; then |
| | | nj=$(echo $gpuid_list | awk -F "," '{print NF}') |
| | | else |
| | | nj=$njob |
| | | batch_size=1 |
| | | gpuid_list="" |
| | | for JOB in $(seq ${nj}); do |
| | | gpuid_list=$gpuid_list"-1," |
| | | done |
| | | fi |
| | | |
| | | mkdir -p $output_dir/split |
| | | split_scps="" |
| | | split_texts="" |
| | | for JOB in $(seq ${nj}); do |
| | | split_scps="$split_scps $output_dir/split/wav.$JOB.scp" |
| | | split_texts="$split_texts $output_dir/split/text.$JOB.scp" |
| | | done |
| | | perl utils/split_scp.pl ${data_dir}/wav.scp ${split_scps} |
| | | perl utils/split_scp.pl ${data_dir}/text.scp ${split_texts} |
| | | |
| | | if [ -n "${checkpoint_dir}" ]; then |
| | | python utils/prepare_checkpoint.py ${model} ${checkpoint_dir} ${checkpoint_name} |
| | | model=${checkpoint_dir}/${model} |
| | | fi |
| | | |
| | | if [ $stage -le 1 ] && [ $stop_stage -ge 1 ];then |
| | | echo "Decoding ..." |
| | | gpuid_list_array=(${gpuid_list//,/ }) |
| | | for JOB in $(seq ${nj}); do |
| | | { |
| | | id=$((JOB-1)) |
| | | gpuid=${gpuid_list_array[$id]} |
| | | mkdir -p ${output_dir}/output.$JOB |
| | | python infer.py \ |
| | | --model ${model} \ |
| | | --audio_in ${output_dir}/split/wav.$JOB.scp \ |
| | | --text_in ${output_dir}/split/text.$JOB.scp \ |
| | | --output_dir ${output_dir}/output.$JOB \ |
| | | --batch_size ${batch_size} \ |
| | | --gpuid ${gpuid} |
| | | }& |
| | | done |
| | | wait |
| | | |
| | | mkdir -p ${output_dir}/timestamp_prediction |
| | | for f in tp_sync tp_time; do |
| | | if [ -f "${output_dir}/output.1/timestamp_prediction/${f}" ]; then |
| | | for i in $(seq "${nj}"); do |
| | | cat "${output_dir}/output.${i}/timestamp_prediction/${f}" |
| | | done | sort -k1 >"${output_dir}/timestamp_prediction/${f}" |
| | | fi |
| | | done |
| | | fi |
| | | |
| New file |
| | |
| | | ../../vad/TEMPLATE/utils |
| | |
| | | import os |
| | | import argparse |
| | | from modelscope.pipelines import pipeline |
| | | from modelscope.utils.constant import Tasks |
| | | |
| | | inference_pipline = pipeline( |
| | | task=Tasks.speech_timestamp, |
| | | model='damo/speech_timestamp_prediction-v1-16k-offline', |
| | | output_dir='./tmp') |
| | | def modelscope_infer(args): |
| | | os.environ['CUDA_VISIBLE_DEVICES'] = str(args.gpuid) |
| | | inference_pipeline = pipeline( |
| | | task=Tasks.speech_timestamp, |
| | | model=args.model, |
| | | output_dir=args.output_dir, |
| | | batch_size=args.batch_size, |
| | | ) |
| | | if args.output_dir is not None: |
| | | inference_pipeline(audio_in=args.audio_in, text_in=args.text_in) |
| | | else: |
| | | print(inference_pipeline(audio_in=args.audio_in, text_in=args.text_in)) |
| | | |
| | | rec_result = inference_pipline( |
| | | audio_in='https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/asr_example_timestamps.wav', |
| | | text_in='一 个 东 太 平 洋 国 家 为 什 么 跑 到 西 太 平 洋 来 了 呢') |
| | | print(rec_result) |
| | | if __name__ == "__main__": |
| | | parser = argparse.ArgumentParser() |
| | | parser.add_argument('--model', type=str, default="damo/speech_timestamp_prediction-v1-16k-offline") |
| | | parser.add_argument('--audio_in', type=str, default="https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/asr_example_timestamps.wav") |
| | | parser.add_argument('--text_in', type=str, default="一 个 东 太 平 洋 国 家 为 什 么 跑 到 西 太 平 洋 来 了 呢") |
| | | parser.add_argument('--output_dir', type=str, default="./results/") |
| | | parser.add_argument('--batch_size', type=int, default=1) |
| | | parser.add_argument('--gpuid', type=str, default="0") |
| | | args = parser.parse_args() |
| | | modelscope_infer(args) |
| | |
| | | # Voice Activity Detection |
| | | |
| | | > **Note**: |
| | | > The modelscope pipeline supports all the models in [model zoo](https://alibaba-damo-academy.github.io/FunASR/en/modelscope_models.html#pretrained-models-on-modelscope) to inference and finetine. Here we take the model of FSMN-VAD as example to demonstrate the usage. |
| | | > The modelscope pipeline supports all the models in [model zoo](https://alibaba-damo-academy.github.io/FunASR/en/modelscope_models.html#pretrained-models-on-modelscope) to inference and finetune. Here we take the model of FSMN-VAD as example to demonstrate the usage. |
| | | |
| | | ## Inference |
| | | |
| | |
| | | - pcm_path, `e.g.`: asr_example.pcm, |
| | | - audio bytes stream, `e.g.`: bytes data from a microphone |
| | | - audio sample point,`e.g.`: `audio, rate = soundfile.read("asr_example_zh.wav")`, the dtype is numpy.ndarray or torch.Tensor |
| | | - wav.scp, kaldi style wav list (`wav_id \t wav_path``), `e.g.`: |
| | | - wav.scp, kaldi style wav list (`wav_id \t wav_path`), `e.g.`: |
| | | ```text |
| | | asr_example1 ./audios/asr_example1.wav |
| | | asr_example2 ./audios/asr_example2.wav |
| | |
| | | split_with_space=split_with_space, |
| | | seg_dict_file=seg_dict_file, |
| | | ) |
| | | |
| | | if output_dir is not None: |
| | | writer = DatadirWriter(output_dir) |
| | | tp_writer = writer[f"timestamp_prediction"] |
| | | # ibest_writer["token_list"][""] = " ".join(speech2text.asr_train_args.token_list) |
| | | else: |
| | | tp_writer = None |
| | | |
| | | def _forward( |
| | | data_path_and_name_and_type, |
| | |
| | | fs: dict = None, |
| | | param_dict: dict = None, |
| | | **kwargs |
| | | ): |
| | | ): |
| | | output_path = output_dir_v2 if output_dir_v2 is not None else output_dir |
| | | writer = None |
| | | if output_path is not None: |
| | | writer = DatadirWriter(output_path) |
| | | tp_writer = writer[f"timestamp_prediction"] |
| | | else: |
| | | tp_writer = None |
| | | # 3. Build data-iterator |
| | | if data_path_and_name_and_type is None and raw_inputs is not None: |
| | | if isinstance(raw_inputs, torch.Tensor): |
| | |
| | | ts_str, ts_list = ts_prediction_lfr6_standard(us_alphas[batch_id], us_cif_peak[batch_id], token, force_time_shift=-3.0) |
| | | logging.warning(ts_str) |
| | | item = {'key': key, 'value': ts_str, 'timestamp':ts_list} |
| | | if tp_writer is not None: |
| | | tp_writer["tp_sync"][key+'#'] = ts_str |
| | | tp_writer["tp_time"][key+'#'] = str(ts_list) |
| | | tp_result_list.append(item) |
| | | return tp_result_list |
| | | |