diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..04298d77cd9726b8143d50277579a28eee000b25 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,8 @@ +FROM ghcr.io/collabora/whisperfusion-base:latest as base + +WORKDIR /root +COPY scripts/setup-whisperfusion.sh scripts/run-whisperfusion.sh scratch-space/models /root/ +RUN ./setup-whisperfusion.sh + +CMD ./run-whisperfusion.sh + diff --git a/README (2).md b/README (2).md new file mode 100644 index 0000000000000000000000000000000000000000..d89385a5dbc570a3e6908e4fc0e5e501bff2ac7c --- /dev/null +++ b/README (2).md @@ -0,0 +1,61 @@ +# WhisperFusion + +

+ WhisperFusion +

Seamless conversations with AI (with ultra-low latency)

+

+ +Welcome to WhisperFusion. WhisperFusion builds upon the capabilities of +the [WhisperLive](https://github.com/collabora/WhisperLive) and +[WhisperSpeech](https://github.com/collabora/WhisperSpeech) by +integrating Mistral, a Large Language Model (LLM), on top of the +real-time speech-to-text pipeline. Both LLM and +Whisper are optimized to run efficiently as TensorRT engines, maximizing +performance and real-time processing capabilities. While WhiperSpeech is +optimized with torch.compile. + +## Features + +- **Real-Time Speech-to-Text**: Utilizes OpenAI WhisperLive to convert + spoken language into text in real-time. + +- **Large Language Model Integration**: Adds Mistral, a Large Language + Model, to enhance the understanding and context of the transcribed + text. + +- **TensorRT Optimization**: Both LLM and Whisper are optimized to + run as TensorRT engines, ensuring high-performance and low-latency + processing. +- **torch.compile**: WhisperSpeech uses torch.compile to speed up + inference which makes PyTorch code run faster by JIT-compiling PyTorch + code into optimized kernels. + +## Getting Started +- We provide a pre-built TensorRT-LLM docker container that has both whisper and + phi converted to TensorRT engines and WhisperSpeech model is pre-downloaded to + quickly start interacting with WhisperFusion. +```bash + docker run --gpus all --shm-size 64G -p 6006:6006 -p 8888:8888 -it ghcr.io/collabora/whisperfusion:latest +``` + +- Start Web GUI +```bash + cd examples/chatbot/html + python -m http.server +``` + +## Build Docker Image +- We provide the docker image for cuda-architecures 89 and 90. If you have a GPU + with a different cuda architecture. For e.g. to build for RTX 3090 with cuda- + architecture 86 +```bash + bash build.sh 86-real +``` +This should build the `ghcr.io/collabora/whisperfusion:latest` for RTX 3090. + +## Contact Us + +For questions or issues, please open an issue. Contact us at: +marcus.edel@collabora.com, jpc@collabora.com, +vineet.suryan@collabora.com diff --git a/README.qmd b/README.qmd new file mode 100644 index 0000000000000000000000000000000000000000..a6c2c9ef932b3c3ebfdf982106d329ddd7befa18 --- /dev/null +++ b/README.qmd @@ -0,0 +1,92 @@ +--- +format: gfm +execute: + echo: false + output: asis +--- + +```{python} +#| include: false +def include_file(fname): + with open(fname) as f: + print(f''' +:::{{.callout-note}} +These steps are included in `{fname}` +::: +''') + code = False + for l in f: + if l.startswith('#!'): + continue + if l.startswith('## '): + if code: print("```"); code=False + print(l[3:]) + elif l.strip(): + if not code: print("```bash"); code=True + print(l.rstrip()) + if code: print("```") +``` + +# WhisperFusion + +

+ WhisperFusion +

Doing math with WhisperFusion: Ultra-low latency conversations with an AI chatbot

+

+ +Welcome to WhisperFusion. WhisperFusion builds upon the capabilities of the [WhisperLive](https://github.com/collabora/WhisperLive) and [WhisperSpeech](https://github.com/collabora/WhisperSpeech) by integrating Mistral, a Large Language Model (LLM), on top of the real-time speech-to-text pipeline. WhisperLive relies on OpenAI Whisper, a powerful automatic speech recognition (ASR) system. Both Mistral and Whisper are optimized to run efficiently as TensorRT engines, maximizing performance and real-time processing capabilities. + +## Features +- **Real-Time Speech-to-Text**: Utilizes OpenAI WhisperLive to convert spoken language into text in real-time. + +- **Large Language Model Integration**: Adds Mistral, a Large Language Model, to enhance the understanding and context of the transcribed text. + +- **TensorRT Optimization**: Both Mistral and Whisper are optimized to run as TensorRT engines, ensuring high-performance and low-latency processing. + +## Prerequisites +Install [TensorRT-LLM](https://github.com/NVIDIA/TensorRT-LLM/blob/main/docs/source/installation.md) to build Whisper and Mistral TensorRT engines. The README builds a docker image for TensorRT-LLM. +Instead of building a docker image, we can also refer to the README and the [Dockerfile.multi](https://github.com/NVIDIA/TensorRT-LLM/blob/main/docker/Dockerfile.multi) to install the required packages in the base pytroch docker image. Just make sure to use the correct base image as mentioned in the dockerfile and everything should go nice and smooth. + +### Build Whisper TensorRT Engine + +```{python} +include_file('docker/scripts/build-whisper.sh') +``` + +### Build Mistral TensorRT Engine + +```{python} +include_file('docker/scripts/build-mistral.sh') +``` + +### Build Phi TensorRT Engine + +```{python} +include_file('docker/scripts/build-phi-2.sh') +``` + +## Build WhisperFusion + +```{python} +include_file('docker/scripts/setup-whisperfusion.sh') +``` + +### Run WhisperFusion with Whisper and Mistral/Phi-2 + +Take the folder path for Whisper TensorRT model, folder_path and tokenizer_path for Mistral/Phi-2 TensorRT from the build phase. If a huggingface model is used to build mistral/phi-2 then just use the huggingface repo name as the tokenizer path. + +```{python} +include_file('docker/scripts/run-whisperfusion.sh') +``` + +- On the client side clone the repo, install the requirements and execute `run_client.py` +```bash +cd WhisperFusion +pip install -r requirements.txt +python3 run_client.py +``` + +## Contact Us +For questions or issues, please open an issue. +Contact us at: marcus.edel@collabora.com, jpc@collabora.com, vineet.suryan@collabora.com diff --git a/assets/1221-135766-0002.wav b/assets/1221-135766-0002.wav new file mode 100644 index 0000000000000000000000000000000000000000..c76bac8aad2de7529570c12089158e9262aa8091 Binary files /dev/null and b/assets/1221-135766-0002.wav differ diff --git a/assets/mel_filters.npz b/assets/mel_filters.npz new file mode 100644 index 0000000000000000000000000000000000000000..cc5204d86199d18f715b92afa2c2b644f176c56c --- /dev/null +++ b/assets/mel_filters.npz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7450ae70723a5ef9d341e3cee628c7cb0177f36ce42c44b7ed2bf3325f0f6d4c +size 4271 diff --git a/build-dolphin-2_6-phi-2.sh b/build-dolphin-2_6-phi-2.sh new file mode 100644 index 0000000000000000000000000000000000000000..8e155ae1479be33dffefb73b6eeba9efdfd1c406 --- /dev/null +++ b/build-dolphin-2_6-phi-2.sh @@ -0,0 +1,26 @@ +#!/bin/bash -e + +## Note: Phi is only available in main branch and hasnt been released yet. So, make sure to build TensorRT-LLM from main branch. + +cd /root/TensorRT-LLM-examples/phi + +## Build TensorRT for [Dolphin Phi Finetuned](https://huggingface.co/cognitivecomputations/dolphin-2_6-phi-2) ChatML format with `fp16` + +git lfs install +phi_path=$(huggingface-cli download --repo-type model cognitivecomputations/dolphin-2_6-phi-2) +name=dolphin-2_6-phi-2 +python3 build.py --dtype=float16 \ + --log_level=verbose \ + --use_gpt_attention_plugin float16 \ + --use_gemm_plugin float16 \ + --max_batch_size=1 \ + --max_input_len=1024 \ + --max_output_len=1024 \ + --output_dir=$name \ + --model_dir="$phi_path" >&1 | tee build.log + +dest=/root/scratch-space/models +mkdir -p "$dest/$name/tokenizer" +cp -r "$name" "$dest" +(cd "$phi_path" && cp config.json tokenizer_config.json vocab.json merges.txt "$dest/$name/tokenizer") +cp -r "$phi_path" "$dest/phi-orig-model" diff --git a/build-mistral.sh b/build-mistral.sh new file mode 100644 index 0000000000000000000000000000000000000000..4c62cc7770d0027cc56162ef33a25fe75ae07382 --- /dev/null +++ b/build-mistral.sh @@ -0,0 +1,18 @@ +#!/bin/bash -e + +cd /root/TensorRT-LLM-examples/llama + +## Build TensorRT for Mistral with `fp16` + +python build.py --model_dir teknium/OpenHermes-2.5-Mistral-7B \ + --dtype float16 \ + --remove_input_padding \ + --use_gpt_attention_plugin float16 \ + --enable_context_fmha \ + --use_gemm_plugin float16 \ + --output_dir ./tmp/mistral/7B/trt_engines/fp16/1-gpu/ \ + --max_input_len 5000 \ + --max_batch_size 1 + +mkdir -p /root/scratch-space/models +cp -r tmp/mistral/7B/trt_engines/fp16/1-gpu /root/scratch-space/models/mistral diff --git a/build-models.sh b/build-models.sh new file mode 100644 index 0000000000000000000000000000000000000000..9571c3a97012ad92e1dd0fae906bb445ebc127a0 --- /dev/null +++ b/build-models.sh @@ -0,0 +1,7 @@ +#!/bin/bash -e + +test -f /etc/shinit_v2 && source /etc/shinit_v2 + +./build-whisper.sh +# ./build-mistral.sh +./build-dolphin-2_6-phi-2.sh diff --git a/build-phi-2.sh b/build-phi-2.sh new file mode 100644 index 0000000000000000000000000000000000000000..7659d19bb203d07c925339446686052f007b26ef --- /dev/null +++ b/build-phi-2.sh @@ -0,0 +1,25 @@ +#!/bin/bash -e + +## Note: Phi is only available in main branch and hasnt been released yet. So, make sure to build TensorRT-LLM from main branch. + +cd /root/TensorRT-LLM-examples/phi + +## Build TensorRT for Phi-2 with `fp16` + +git lfs install +phi_path=$(huggingface-cli download --repo-type model --revision 834565c23f9b28b96ccbeabe614dd906b6db551a microsoft/phi-2) +python3 build.py --dtype=float16 \ + --log_level=verbose \ + --use_gpt_attention_plugin float16 \ + --use_gemm_plugin float16 \ + --max_batch_size=16 \ + --max_input_len=1024 \ + --max_output_len=1024 \ + --output_dir=phi-2 \ + --model_dir="$phi_path" >&1 | tee build.log + +dest=/root/scratch-space/models +mkdir -p "$dest/phi-2/tokenizer" +cp -r phi-2 "$dest" +(cd "$phi_path" && cp config.json tokenizer_config.json vocab.json merges.txt "$dest/phi-2/tokenizer") +cp -r "$phi_path" "$dest/phi-orig-model" diff --git a/build-whisper.sh b/build-whisper.sh new file mode 100644 index 0000000000000000000000000000000000000000..383a0b1884bf5a962f42be98bac6fd3616869c97 --- /dev/null +++ b/build-whisper.sh @@ -0,0 +1,33 @@ +#!/bin/bash -e + +## Change working dir to the [whisper example dir](https://github.com/NVIDIA/TensorRT-LLM/tree/main/examples/whisper) in TensorRT-LLM. +cd /root/TensorRT-LLM-examples/whisper + +## Currently, by default TensorRT-LLM only supports `large-v2` and `large-v3`. In this repo, we use `small.en`. +## Download the required assets + +# the sound filter definitions +wget --directory-prefix=assets https://raw.githubusercontent.com/openai/whisper/main/whisper/assets/mel_filters.npz +# the small.en model weights +wget --directory-prefix=assets https://openaipublic.azureedge.net/main/whisper/models/f953ad0fd29cacd07d5a9eda5624af0f6bcf2258be67c92b79389873d91e0872/small.en.pt + +## We have to patch the script to add support for out model size (`small.en`): +patch <&1 | tee build.log + +dest=/root/scratch-space/models +mkdir -p "$dest/$name/tokenizer" +cp -r "$name" "$dest" +(cd "$phi_path" && cp config.json tokenizer_config.json vocab.json merges.txt "$dest/$name/tokenizer") +cp -r "$phi_path" "$dest/phi-orig-model" diff --git a/docker/scripts/build-mistral.sh b/docker/scripts/build-mistral.sh new file mode 100644 index 0000000000000000000000000000000000000000..4c62cc7770d0027cc56162ef33a25fe75ae07382 --- /dev/null +++ b/docker/scripts/build-mistral.sh @@ -0,0 +1,18 @@ +#!/bin/bash -e + +cd /root/TensorRT-LLM-examples/llama + +## Build TensorRT for Mistral with `fp16` + +python build.py --model_dir teknium/OpenHermes-2.5-Mistral-7B \ + --dtype float16 \ + --remove_input_padding \ + --use_gpt_attention_plugin float16 \ + --enable_context_fmha \ + --use_gemm_plugin float16 \ + --output_dir ./tmp/mistral/7B/trt_engines/fp16/1-gpu/ \ + --max_input_len 5000 \ + --max_batch_size 1 + +mkdir -p /root/scratch-space/models +cp -r tmp/mistral/7B/trt_engines/fp16/1-gpu /root/scratch-space/models/mistral diff --git a/docker/scripts/build-models.sh b/docker/scripts/build-models.sh new file mode 100644 index 0000000000000000000000000000000000000000..9571c3a97012ad92e1dd0fae906bb445ebc127a0 --- /dev/null +++ b/docker/scripts/build-models.sh @@ -0,0 +1,7 @@ +#!/bin/bash -e + +test -f /etc/shinit_v2 && source /etc/shinit_v2 + +./build-whisper.sh +# ./build-mistral.sh +./build-dolphin-2_6-phi-2.sh diff --git a/docker/scripts/build-phi-2.sh b/docker/scripts/build-phi-2.sh new file mode 100644 index 0000000000000000000000000000000000000000..7659d19bb203d07c925339446686052f007b26ef --- /dev/null +++ b/docker/scripts/build-phi-2.sh @@ -0,0 +1,25 @@ +#!/bin/bash -e + +## Note: Phi is only available in main branch and hasnt been released yet. So, make sure to build TensorRT-LLM from main branch. + +cd /root/TensorRT-LLM-examples/phi + +## Build TensorRT for Phi-2 with `fp16` + +git lfs install +phi_path=$(huggingface-cli download --repo-type model --revision 834565c23f9b28b96ccbeabe614dd906b6db551a microsoft/phi-2) +python3 build.py --dtype=float16 \ + --log_level=verbose \ + --use_gpt_attention_plugin float16 \ + --use_gemm_plugin float16 \ + --max_batch_size=16 \ + --max_input_len=1024 \ + --max_output_len=1024 \ + --output_dir=phi-2 \ + --model_dir="$phi_path" >&1 | tee build.log + +dest=/root/scratch-space/models +mkdir -p "$dest/phi-2/tokenizer" +cp -r phi-2 "$dest" +(cd "$phi_path" && cp config.json tokenizer_config.json vocab.json merges.txt "$dest/phi-2/tokenizer") +cp -r "$phi_path" "$dest/phi-orig-model" diff --git a/docker/scripts/build-whisper.sh b/docker/scripts/build-whisper.sh new file mode 100644 index 0000000000000000000000000000000000000000..383a0b1884bf5a962f42be98bac6fd3616869c97 --- /dev/null +++ b/docker/scripts/build-whisper.sh @@ -0,0 +1,33 @@ +#!/bin/bash -e + +## Change working dir to the [whisper example dir](https://github.com/NVIDIA/TensorRT-LLM/tree/main/examples/whisper) in TensorRT-LLM. +cd /root/TensorRT-LLM-examples/whisper + +## Currently, by default TensorRT-LLM only supports `large-v2` and `large-v3`. In this repo, we use `small.en`. +## Download the required assets + +# the sound filter definitions +wget --directory-prefix=assets https://raw.githubusercontent.com/openai/whisper/main/whisper/assets/mel_filters.npz +# the small.en model weights +wget --directory-prefix=assets https://openaipublic.azureedge.net/main/whisper/models/f953ad0fd29cacd07d5a9eda5624af0f6bcf2258be67c92b79389873d91e0872/small.en.pt + +## We have to patch the script to add support for out model size (`small.en`): +patch <li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-acquisitions-incorporated:before{content:"\f6af"}.fa-ad:before{content:"\f641"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-air-freshener:before{content:"\f5d0"}.fa-airbnb:before{content:"\f834"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-alipay:before{content:"\f642"}.fa-allergies:before{content:"\f461"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angry:before{content:"\f556"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-ankh:before{content:"\f644"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-alt:before{content:"\f5d1"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-archway:before{content:"\f557"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-artstation:before{content:"\f77a"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-atlas:before{content:"\f558"}.fa-atlassian:before{content:"\f77b"}.fa-atom:before{content:"\f5d2"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-award:before{content:"\f559"}.fa-aws:before{content:"\f375"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before{content:"\f77d"}.fa-backspace:before{content:"\f55a"}.fa-backward:before{content:"\f04a"}.fa-bacon:before{content:"\f7e5"}.fa-bacteria:before{content:"\e059"}.fa-bacterium:before{content:"\e05a"}.fa-bahai:before{content:"\f666"}.fa-balance-scale:before{content:"\f24e"}.fa-balance-scale-left:before{content:"\f515"}.fa-balance-scale-right:before{content:"\f516"}.fa-ban:before{content:"\f05e"}.fa-band-aid:before{content:"\f462"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-baseball-ball:before{content:"\f433"}.fa-basketball-ball:before{content:"\f434"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-battle-net:before{content:"\f835"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bible:before{content:"\f647"}.fa-bicycle:before{content:"\f206"}.fa-biking:before{content:"\f84a"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blind:before{content:"\f29d"}.fa-blog:before{content:"\f781"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-book-dead:before{content:"\f6b7"}.fa-book-medical:before{content:"\f7e6"}.fa-book-open:before{content:"\f518"}.fa-book-reader:before{content:"\f5da"}.fa-bookmark:before{content:"\f02e"}.fa-bootstrap:before{content:"\f836"}.fa-border-all:before{content:"\f84c"}.fa-border-none:before{content:"\f850"}.fa-border-style:before{content:"\f853"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-box-open:before{content:"\f49e"}.fa-box-tissue:before{content:"\e05b"}.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-bread-slice:before{content:"\f7ec"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broadcast-tower:before{content:"\f519"}.fa-broom:before{content:"\f51a"}.fa-brush:before{content:"\f55d"}.fa-btc:before{content:"\f15a"}.fa-buffer:before{content:"\f837"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burn:before{content:"\f46a"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before{content:"\f55e"}.fa-business-time:before{content:"\f64a"}.fa-buy-n-large:before{content:"\f8a6"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-calendar-week:before{content:"\f784"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-campground:before{content:"\f6bb"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-car:before{content:"\f1b9"}.fa-car-alt:before{content:"\f5de"}.fa-car-battery:before{content:"\f5df"}.fa-car-crash:before{content:"\f5e1"}.fa-car-side:before{content:"\f5e4"}.fa-caravan:before{content:"\f8ff"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before{content:"\f51c"}.fa-charging-station:before{content:"\f5e7"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-double:before{content:"\f560"}.fa-check-square:before{content:"\f14a"}.fa-cheese:before{content:"\f7ef"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-chromecast:before{content:"\f838"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-city:before{content:"\f64f"}.fa-clinic-medical:before{content:"\f7f2"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudflare:before{content:"\e07d"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cocktail:before{content:"\f561"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-coins:before{content:"\f51e"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before{content:"\f4ad"}.fa-comment-medical:before{content:"\f7f5"}.fa-comment-slash:before{content:"\f4b3"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-compress-alt:before{content:"\f422"}.fa-compress-arrows-alt:before{content:"\f78c"}.fa-concierge-bell:before{content:"\f562"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-cotton-bureau:before{content:"\f89e"}.fa-couch:before{content:"\f4b8"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-credit-card:before{content:"\f09d"}.fa-critical-role:before{content:"\f6c9"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-crutch:before{content:"\f7f7"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dailymotion:before{content:"\e052"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-deezer:before{content:"\e077"}.fa-delicious:before{content:"\f1a5"}.fa-democrat:before{content:"\f747"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dharmachakra:before{content:"\f655"}.fa-dhl:before{content:"\f790"}.fa-diagnoses:before{content:"\f470"}.fa-diaspora:before{content:"\f791"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-digital-tachograph:before{content:"\f566"}.fa-directions:before{content:"\f5eb"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-disease:before{content:"\f7fa"}.fa-divide:before{content:"\f529"}.fa-dizzy:before{content:"\f567"}.fa-dna:before{content:"\f471"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before{content:"\f155"}.fa-dolly:before{content:"\f472"}.fa-dolly-flatbed:before{content:"\f474"}.fa-donate:before{content:"\f4b9"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dot-circle:before{content:"\f192"}.fa-dove:before{content:"\f4ba"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-drafting-compass:before{content:"\f568"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-drupal:before{content:"\f1a9"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edge-legacy:before{content:"\e078"}.fa-edit:before{content:"\f044"}.fa-egg:before{content:"\f7fb"}.fa-eject:before{content:"\f052"}.fa-elementor:before{content:"\f430"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-equals:before{content:"\f52c"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-ethernet:before{content:"\f796"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-evernote:before{content:"\f839"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-alt:before{content:"\f424"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fan:before{content:"\f863"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-faucet:before{content:"\e005"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before{content:"\f56b"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-figma:before{content:"\f799"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-download:before{content:"\f56d"}.fa-file-excel:before{content:"\f1c3"}.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-medical:before{content:"\f477"}.fa-file-medical-alt:before{content:"\f478"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-signature:before{content:"\f573"}.fa-file-upload:before{content:"\f574"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-alt:before{content:"\f7e4"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-firefox-browser:before{content:"\e007"}.fa-first-aid:before{content:"\f479"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-fish:before{content:"\f578"}.fa-fist-raised:before{content:"\f6de"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-flushed:before{content:"\f579"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-font-awesome-logo-full:before{content:"\f4e6"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-football-ball:before{content:"\f44e"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frog:before{content:"\f52e"}.fa-frown:before{content:"\f119"}.fa-frown-open:before{content:"\f57a"}.fa-fulcrum:before{content:"\f50b"}.fa-funnel-dollar:before{content:"\f662"}.fa-futbol:before{content:"\f1e3"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-git:before{content:"\f1d3"}.fa-git-alt:before{content:"\f841"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-cheers:before{content:"\f79f"}.fa-glass-martini:before{content:"\f000"}.fa-glass-martini-alt:before{content:"\f57b"}.fa-glass-whiskey:before{content:"\f7a0"}.fa-glasses:before{content:"\f530"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-globe-africa:before{content:"\f57c"}.fa-globe-americas:before{content:"\f57d"}.fa-globe-asia:before{content:"\f57e"}.fa-globe-europe:before{content:"\f7a2"}.fa-gofore:before{content:"\f3a7"}.fa-golf-ball:before{content:"\f450"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-pay:before{content:"\e079"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-greater-than:before{content:"\f531"}.fa-greater-than-equal:before{content:"\f532"}.fa-grimace:before{content:"\f57f"}.fa-grin:before{content:"\f580"}.fa-grin-alt:before{content:"\f581"}.fa-grin-beam:before{content:"\f582"}.fa-grin-beam-sweat:before{content:"\f583"}.fa-grin-hearts:before{content:"\f584"}.fa-grin-squint:before{content:"\f585"}.fa-grin-squint-tears:before{content:"\f586"}.fa-grin-stars:before{content:"\f587"}.fa-grin-tears:before{content:"\f588"}.fa-grin-tongue:before{content:"\f589"}.fa-grin-tongue-squint:before{content:"\f58a"}.fa-grin-tongue-wink:before{content:"\f58b"}.fa-grin-wink:before{content:"\f58c"}.fa-grip-horizontal:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guilded:before{content:"\e07e"}.fa-guitar:before{content:"\f7a6"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hamburger:before{content:"\f805"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-medical:before{content:"\e05c"}.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-holding-water:before{content:"\f4c1"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-middle-finger:before{content:"\f806"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-sparkles:before{content:"\e05d"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-hands-wash:before{content:"\e05e"}.fa-handshake:before{content:"\f2b5"}.fa-handshake-alt-slash:before{content:"\e05f"}.fa-handshake-slash:before{content:"\e060"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-hat:before{content:"\f807"}.fa-hashtag:before{content:"\f292"}.fa-hat-cowboy:before{content:"\f8c0"}.fa-hat-cowboy-side:before{content:"\f8c1"}.fa-hat-wizard:before{content:"\f6e8"}.fa-hdd:before{content:"\f0a0"}.fa-head-side-cough:before{content:"\e061"}.fa-head-side-cough-slash:before{content:"\e062"}.fa-head-side-mask:before{content:"\e063"}.fa-head-side-virus:before{content:"\e064"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-broken:before{content:"\f7a9"}.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-highlighter:before{content:"\f591"}.fa-hiking:before{content:"\f6ec"}.fa-hippo:before{content:"\f6ed"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-hive:before{content:"\e07f"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital:before{content:"\f0f8"}.fa-hospital-alt:before{content:"\f47d"}.fa-hospital-symbol:before{content:"\f47e"}.fa-hospital-user:before{content:"\f80d"}.fa-hot-tub:before{content:"\f593"}.fa-hotdog:before{content:"\f80f"}.fa-hotel:before{content:"\f594"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-house-damage:before{content:"\f6f1"}.fa-house-user:before{content:"\e065"}.fa-houzz:before{content:"\f27c"}.fa-hryvnia:before{content:"\f6f2"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-ice-cream:before{content:"\f810"}.fa-icicles:before{content:"\f7ad"}.fa-icons:before{content:"\f86d"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before{content:"\f47f"}.fa-ideal:before{content:"\e013"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-innosoft:before{content:"\e080"}.fa-instagram:before{content:"\f16d"}.fa-instagram-square:before{content:"\e055"}.fa-instalod:before{content:"\e081"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itch-io:before{content:"\f83a"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi:before{content:"\f669"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joint:before{content:"\f595"}.fa-joomla:before{content:"\f1aa"}.fa-journal-whills:before{content:"\f66a"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaaba:before{content:"\f66b"}.fa-kaggle:before{content:"\f5fa"}.fa-key:before{content:"\f084"}.fa-keybase:before{content:"\f4f5"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-khanda:before{content:"\f66d"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-kiss:before{content:"\f596"}.fa-kiss-beam:before{content:"\f597"}.fa-kiss-wink-heart:before{content:"\f598"}.fa-kiwi-bird:before{content:"\f535"}.fa-korvue:before{content:"\f42f"}.fa-landmark:before{content:"\f66f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laptop-house:before{content:"\e066"}.fa-laptop-medical:before{content:"\f812"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-laugh:before{content:"\f599"}.fa-laugh-beam:before{content:"\f59a"}.fa-laugh-squint:before{content:"\f59b"}.fa-laugh-wink:before{content:"\f59c"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-less-than:before{content:"\f536"}.fa-less-than-equal:before{content:"\f537"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-luggage-cart:before{content:"\f59d"}.fa-lungs:before{content:"\f604"}.fa-lungs-virus:before{content:"\e067"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-mail-bulk:before{content:"\f674"}.fa-mailchimp:before{content:"\f59e"}.fa-male:before{content:"\f183"}.fa-mandalorian:before{content:"\f50f"}.fa-map:before{content:"\f279"}.fa-map-marked:before{content:"\f59f"}.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-markdown:before{content:"\f60f"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mask:before{content:"\f6fa"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-mdb:before{content:"\f8ca"}.fa-medal:before{content:"\f5a2"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-meh:before{content:"\f11a"}.fa-meh-blank:before{content:"\f5a4"}.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-memory:before{content:"\f538"}.fa-mendeley:before{content:"\f7b3"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-meteor:before{content:"\f753"}.fa-microblog:before{content:"\e01a"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before{content:"\f3c9"}.fa-microphone-alt-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mitten:before{content:"\f7b5"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mixer:before{content:"\e056"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-motorcycle:before{content:"\f21c"}.fa-mountain:before{content:"\f6fc"}.fa-mouse:before{content:"\f8cc"}.fa-mouse-pointer:before{content:"\f245"}.fa-mug-hot:before{content:"\f7b6"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nimblr:before{content:"\f5a8"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-not-equal:before{content:"\f53e"}.fa-notes-medical:before{content:"\f481"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-octopus-deploy:before{content:"\e082"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-oil-can:before{content:"\f613"}.fa-old-republic:before{content:"\f510"}.fa-om:before{content:"\f679"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-orcid:before{content:"\f8d2"}.fa-osi:before{content:"\f41a"}.fa-otter:before{content:"\f700"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-pager:before{content:"\f815"}.fa-paint-brush:before{content:"\f1fc"}.fa-paint-roller:before{content:"\f5aa"}.fa-palette:before{content:"\f53f"}.fa-palfed:before{content:"\f3d8"}.fa-pallet:before{content:"\f482"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-parking:before{content:"\f540"}.fa-passport:before{content:"\f5ab"}.fa-pastafarianism:before{content:"\f67b"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-pencil-ruler:before{content:"\f5ae"}.fa-penny-arcade:before{content:"\f704"}.fa-people-arrows:before{content:"\e068"}.fa-people-carry:before{content:"\f4ce"}.fa-pepper-hot:before{content:"\f816"}.fa-perbyte:before{content:"\e083"}.fa-percent:before{content:"\f295"}.fa-percentage:before{content:"\f541"}.fa-periscope:before{content:"\f3da"}.fa-person-booth:before{content:"\f756"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-phone:before{content:"\f095"}.fa-phone-alt:before{content:"\f879"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-square:before{content:"\f098"}.fa-phone-square-alt:before{content:"\f87b"}.fa-phone-volume:before{content:"\f2a0"}.fa-photo-video:before{content:"\f87c"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-square:before{content:"\e01e"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-pizza-slice:before{content:"\f818"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-departure:before{content:"\f5b0"}.fa-plane-slash:before{content:"\e069"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-poll:before{content:"\f681"}.fa-poll-h:before{content:"\f682"}.fa-poo:before{content:"\f2fe"}.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-portrait:before{content:"\f3e0"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-pray:before{content:"\f683"}.fa-praying-hands:before{content:"\f684"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-procedures:before{content:"\f487"}.fa-product-hunt:before{content:"\f288"}.fa-project-diagram:before{content:"\f542"}.fa-pump-medical:before{content:"\e06a"}.fa-pump-soap:before{content:"\e06b"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quidditch:before{content:"\f458"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-quran:before{content:"\f687"}.fa-r-project:before{content:"\f4f7"}.fa-radiation:before{content:"\f7b9"}.fa-radiation-alt:before{content:"\f7ba"}.fa-rainbow:before{content:"\f75b"}.fa-random:before{content:"\f074"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-receipt:before{content:"\f543"}.fa-record-vinyl:before{content:"\f8d9"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redhat:before{content:"\f7bc"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-remove-format:before{content:"\f87d"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-republican:before{content:"\f75e"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-rev:before{content:"\f5b2"}.fa-ribbon:before{content:"\f4d6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-route:before{content:"\f4d7"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-running:before{content:"\f70c"}.fa-rupee-sign:before{content:"\f156"}.fa-rust:before{content:"\e07a"}.fa-sad-cry:before{content:"\f5b3"}.fa-sad-tear:before{content:"\f5b4"}.fa-safari:before{content:"\f267"}.fa-salesforce:before{content:"\f83b"}.fa-sass:before{content:"\f41e"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-school:before{content:"\f549"}.fa-screwdriver:before{content:"\f54a"}.fa-scribd:before{content:"\f28a"}.fa-scroll:before{content:"\f70e"}.fa-sd-card:before{content:"\f7c2"}.fa-search:before{content:"\f002"}.fa-search-dollar:before{content:"\f688"}.fa-search-location:before{content:"\f689"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-seedling:before{content:"\f4d8"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-shapes:before{content:"\f61f"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-shield-virus:before{content:"\e06c"}.fa-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.fa-shopify:before{content:"\e057"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shopware:before{content:"\f5b5"}.fa-shower:before{content:"\f2cc"}.fa-shuttle-van:before{content:"\f5b6"}.fa-sign:before{content:"\f4d9"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-sim-card:before{content:"\f7c4"}.fa-simplybuilt:before{content:"\f215"}.fa-sink:before{content:"\e06d"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-sith:before{content:"\f512"}.fa-skating:before{content:"\f7c5"}.fa-sketch:before{content:"\f7c6"}.fa-skiing:before{content:"\f7c9"}.fa-skiing-nordic:before{content:"\f7ca"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-smile-beam:before{content:"\f5b8"}.fa-smile-wink:before{content:"\f4da"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-smoking-ban:before{content:"\f54d"}.fa-sms:before{content:"\f7cd"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowboarding:before{content:"\f7ce"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-soap:before{content:"\e06e"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-down-alt:before{content:"\f884"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-amount-up-alt:before{content:"\f885"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-spa:before{content:"\f5bb"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-speaker-deck:before{content:"\f83c"}.fa-spell-check:before{content:"\f891"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spotify:before{content:"\f1bc"}.fa-spray-can:before{content:"\f5bd"}.fa-square:before{content:"\f0c8"}.fa-square-full:before{content:"\f45c"}.fa-square-root-alt:before{content:"\f698"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stackpath:before{content:"\f842"}.fa-stamp:before{content:"\f5bf"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-stopwatch:before{content:"\f2f2"}.fa-stopwatch-20:before{content:"\e06f"}.fa-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.fa-store-alt-slash:before{content:"\e070"}.fa-store-slash:before{content:"\e071"}.fa-strava:before{content:"\f428"}.fa-stream:before{content:"\f550"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-stroopwafel:before{content:"\f551"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-surprise:before{content:"\f5c2"}.fa-suse:before{content:"\f7d6"}.fa-swatchbook:before{content:"\f5c3"}.fa-swift:before{content:"\f8e1"}.fa-swimmer:before{content:"\f5c4"}.fa-swimming-pool:before{content:"\f5c5"}.fa-symfony:before{content:"\f83d"}.fa-synagogue:before{content:"\f69b"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-syringe:before{content:"\f48e"}.fa-table:before{content:"\f0ce"}.fa-table-tennis:before{content:"\f45d"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-teamspeak:before{content:"\f4f9"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-tenge:before{content:"\f7d7"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-the-red-yeti:before{content:"\f69d"}.fa-theater-masks:before{content:"\f630"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer:before{content:"\f491"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-think-peaks:before{content:"\f731"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-tiktok:before{content:"\e07b"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-tint-slash:before{content:"\f5c7"}.fa-tired:before{content:"\f5c8"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toilet-paper-slash:before{content:"\e072"}.fa-toolbox:before{content:"\f552"}.fa-tools:before{content:"\f7d9"}.fa-tooth:before{content:"\f5c9"}.fa-torah:before{content:"\f6a0"}.fa-torii-gate:before{content:"\f6a1"}.fa-tractor:before{content:"\f722"}.fa-trade-federation:before{content:"\f513"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-trailer:before{content:"\e041"}.fa-train:before{content:"\f238"}.fa-tram:before{content:"\f7da"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-trash-restore:before{content:"\f829"}.fa-trash-restore-alt:before{content:"\f82a"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-tripadvisor:before{content:"\f262"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-truck-loading:before{content:"\f4de"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-tshirt:before{content:"\f553"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbraco:before{content:"\f8e8"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-uncharted:before{content:"\e084"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-unity:before{content:"\e049"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-unsplash:before{content:"\e07c"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-alt:before{content:"\f406"}.fa-user-alt-slash:before{content:"\f4fa"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-clock:before{content:"\f4fd"}.fa-user-cog:before{content:"\f4fe"}.fa-user-edit:before{content:"\f4ff"}.fa-user-friends:before{content:"\f500"}.fa-user-graduate:before{content:"\f501"}.fa-user-injured:before{content:"\f728"}.fa-user-lock:before{content:"\f502"}.fa-user-md:before{content:"\f0f0"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-nurse:before{content:"\f82f"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before{content:"\f509"}.fa-users-slash:before{content:"\e073"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-vest:before{content:"\e085"}.fa-vest-patches:before{content:"\e086"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-virus:before{content:"\e074"}.fa-virus-slash:before{content:"\e075"}.fa-viruses:before{content:"\e076"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-voicemail:before{content:"\f897"}.fa-volleyball-ball:before{content:"\f45f"}.fa-volume-down:before{content:"\f027"}.fa-volume-mute:before{content:"\f6a9"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vote-yea:before{content:"\f772"}.fa-vr-cardboard:before{content:"\f729"}.fa-vuejs:before{content:"\f41f"}.fa-walking:before{content:"\f554"}.fa-wallet:before{content:"\f555"}.fa-warehouse:before{content:"\f494"}.fa-watchman-monitoring:before{content:"\e087"}.fa-water:before{content:"\f773"}.fa-wave-square:before{content:"\f83e"}.fa-waze:before{content:"\f83f"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weight:before{content:"\f496"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-wind:before{content:"\f72e"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before{content:"\f5ce"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wodu:before{content:"\e088"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wpressr:before{content:"\f3e4"}.fa-wrench:before{content:"\f0ad"}.fa-x-ray:before{content:"\f497"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yammer:before{content:"\f840"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:"Font Awesome 5 Brands"}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.fab,.far{font-weight:400}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.far,.fas{font-family:"Font Awesome 5 Free"}.fa,.fas{font-weight:900} \ No newline at end of file diff --git a/examples/chatbot/html/css/style.css b/examples/chatbot/html/css/style.css new file mode 100644 index 0000000000000000000000000000000000000000..5654797b80667cce81bb5b21d41d9a007a0062f5 --- /dev/null +++ b/examples/chatbot/html/css/style.css @@ -0,0 +1,437 @@ +/* Import Google font - Poppins */ +@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap'); +*{ + /* margin: 0px; + padding: 0px; */ + box-sizing: border-box; + font-family: "Poppins", sans-serif; +} +html, body { + height: 100%; +} + +html { + display: table; + /* margin: auto; */ +} + + +body{ + /* display: flex; */ + align-items: center; + /* justify-content: center; */ + min-height: 100vh; + background: #EBECF2; + + display: table-cell; + vertical-align: middle; + + margin: 0 !important; + padding: 0 !important; + + + +} + + +.avatar-container { +text-align: left; +display: grid; +grid-template-columns: auto auto 1fr; +grid-gap: 0px; +padding-left:0px; +padding-top: 2px; +margin-top: 10px; +} + +.text-container { +text-align: left; +display: grid; +grid-template-columns: auto 1fr; +grid-gap: 0px; +padding-left:0px; +padding-top: 8px; +} + +.llm-timing-container { +text-align: left; +display: grid; +grid-template-columns: auto auto 1fr; +grid-gap: 4px; +padding-left:0px; +padding-top: 8px; +font-size: 12px; +} + +.transcription-timing-container { +text-align: left; +display: grid; +grid-template-columns: auto auto 1fr; +grid-gap: 4px; +padding-left:0px; +padding-top: 8px; +font-size: 12px; +} + +.whisperspeech-timing-container { +text-align: left; +display: grid; +grid-template-columns: auto 1fr; +grid-gap: 4px; +padding-left:0px; +padding-top: 8px; +font-size: 12px; +} + +.whisperspeech-audio-container { + text-align: left; + display: grid; + grid-template-columns: 1fr auto 1fr; + grid-gap: 4px; + padding-left:0px; + padding-top: 8px; + font-size: 12px; + } + +.control-container { +text-align: left; +display: grid; +grid-template-columns: auto auto 20px auto auto auto 1fr; +grid-gap: 4px; +padding-left:0px; +font-size: 12px; +} + + +.avatar { +border-radius: 50%; +width: 24px; +float: left; +} + +.avatar-name { +font-size:15px; +padding-left:4px; +padding-top:2px +} + + + + + + + + + + + + + + + + + +::selection{ + color: #fff; +} +.wrapper{ + width: 430px; + background: #fff; + border-radius: 5px; + padding: 30px; + box-shadow: 7px 7px 12px rgba(0,0,0,0.05); +} +.wrapper header{ + /* color: #6990F2; */ + font-size: 27px; + font-weight: 600; + text-align: center; +} +.wrapper form{ + height: 167px; + display: flex; + cursor: pointer; + margin: 30px 0; + align-items: center; + justify-content: center; + flex-direction: column; + border-radius: 5px; + border: 2px dashed #6990F2; + background-color: #F7FBFF; +} +form :where(i, p){ + /* color: #6990F2; */ +} +form i{ + font-size: 50px; +} +form p{ + margin-top: 15px; + font-size: 16px; +} + +.row { + border: 0.01em solid lightgray; +} + +section .row{ + margin-bottom: 10px; + background: #E9F0FF; + list-style: none; + padding: 15px 20px; + border-radius: 5px; + display: flex; + align-items: center; + justify-content: space-between; +} +section .row i{ + /* color: #6990F2; */ + font-size: 30px; +} +section .details span{ + font-size: 14px; +} +.progress-area .row .content{ + width: 100%; + margin-left: 15px; +} +.progress-area .details{ + display: flex; + align-items: center; + margin-bottom: 7px; + justify-content: space-between; +} +.progress-area .content .progress-bar{ + height: 6px; + width: 100%; + margin-bottom: 4px; + background: #fff; + border-radius: 30px; +} +.content .progress-bar .progress{ + height: 100%; + width: 0%; + border-radius: inherit; +} +.uploaded-area{ + max-height: 232px; + overflow-y: scroll; +} +.uploaded-area.onprogress{ + max-height: 150px; +} +.uploaded-area::-webkit-scrollbar{ + width: 0px; +} +.uploaded-area .row .content{ + display: flex; + align-items: center; +} +.uploaded-area .row .details{ + display: flex; + margin-left: 15px; + flex-direction: column; +} + +.uploaded-area .row .details .size{ + color: #404040; + font-size: 11px; +} +.uploaded-area i.fa-check{ + font-size: 16px; +} + + +.upload-container-title { +text-align: left; +display: grid; +grid-template-columns: auto auto 1fr; +grid-gap: 6px; +padding-left:0px; +/* background-color: #F8F8F8; */ +padding-top:0px; +font-weight: 400; +} + +.name { + font-size: 12px; + text-align: left; +} + + +.process-container-chart { + text-align: left; + display: grid; + grid-template-columns: 50% 50%; + grid-gap: 6px; + padding-left:0px; + /* background-color: #F8F8F8; */ + padding-top:0px; + font-weight: 400; + } + + + + + + + + + + + + + +.radial { + width: 16vh; + height: 16vh; + margin: auto; + position: relative; +} +.ring { + position: absolute; + top: 0%; + left: 0%; + transform: rotateZ(0); + width: 100%; + height: 100%; + color: hsl(40, 100%, 60%); +} +.ring:before { + pointer-events: none; + content: ''; + border: 1.5vh solid hsla(40, 100%, 60%, 0.25); + border-radius: 60vh; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; +} +.ring .label { + position: absolute; + width: 7em; + text-align: right; + font-size: 2.025vh; + font-weight: 300; + line-height: 1.5vh; + right: 50%; + transform: translate3d(-20%, 0, 0); + text-transform: uppercase; + letter-spacing: 0.5em; + z-index: 10; + color: transparent; +} +.dot { + width: 1.5vh; + height: 50%; + position: absolute; + top: 0; + left: 50%; + transform: rotateZ(0deg); + transform-origin: 0 100%; + transform-style: preserve-3d; +} +.dot:before { + content: ''; + display: inline-block; + width: 5.4vh; + height: 1.5vh; + border-radius: 100%; + background: hsl(40, 100%, 60%); + transform: translate3d(-50%, 0, 0) scale(0); + opacity: 0; + transition: transform 0.6s, opacity 0.6s; +} +.dot.val:before { + transform: translate3d(-50%, 0, 0) scale(1); + opacity: 1; +} +.ring:nth-child(4) { + width: 10%; + height: 10%; + top: 45%; + left: 45%; + color: hsl(355, 100%, 60%); + -webkit-animation-delay: 0.75s; + animation-delay: 0.75s; +} +.ring:nth-child(4):before { + border-color: hsla(355, 100%, 60%, 0.25); +} +.ring:nth-child(4) .dot:before { + background: hsl(355, 100%, 60%); +} +.ring:nth-child(3) { + width: 40%; + height: 40%; + top: 30%; + left: 30%; + color: hsl(10, 100%, 60%); + -webkit-animation-delay: 0.5s; + animation-delay: 0.5s; +} +.ring:nth-child(3):before { + border-color: hsla(10, 100%, 60%, 0.25); +} +.ring:nth-child(3) .dot:before { + background: hsl(10, 100%, 60%); +} +.ring:nth-child(2) { + width: 70%; + height: 70%; + top: 15%; + left: 15%; + color: hsl(25, 100%, 60%); + -webkit-animation-delay: 0.25s; + animation-delay: 0.25s; +} +.ring:nth-child(2):before { + border-color: hsla(25, 100%, 60%, 0.25); +} +.ring:nth-child(2) .dot:before { + background: hsl(25, 100%, 60%); +} +@-webkit-keyframes spin { + to { + transform: rotateZ(1turn); + } +} +@keyframes spin { + to { + transform: rotateZ(1turn); + } +} +.slides { + opacity: 0.35; + margin: 5vh 0; + text-align: center; +} +.slides input { + display: inline-block; +} +*, +* :before, +* :after { + box-sizing: border-box; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; +} + +summary { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + + +.button-item { + cursor: pointer; +} + +.audio-container { +margin-top:14px; +} \ No newline at end of file diff --git a/examples/chatbot/html/img/0.png b/examples/chatbot/html/img/0.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8c4c818f299b05c92e40f302f0bf495c3ce6ba Binary files /dev/null and b/examples/chatbot/html/img/0.png differ diff --git a/examples/chatbot/html/img/1.png b/examples/chatbot/html/img/1.png new file mode 100644 index 0000000000000000000000000000000000000000..649c5fc63d60266d965d137a48e416cd68270eac Binary files /dev/null and b/examples/chatbot/html/img/1.png differ diff --git a/examples/chatbot/html/img/2.png b/examples/chatbot/html/img/2.png new file mode 100644 index 0000000000000000000000000000000000000000..c74102fcc276a71372e5042a2fa4091c40c3e2b5 Binary files /dev/null and b/examples/chatbot/html/img/2.png differ diff --git a/examples/chatbot/html/img/COL-logo.png b/examples/chatbot/html/img/COL-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..7dced9121be7ef28430dfdda4c8b9259e9ef1a8a Binary files /dev/null and b/examples/chatbot/html/img/COL-logo.png differ diff --git a/examples/chatbot/html/img/Collabora_Logo.svg b/examples/chatbot/html/img/Collabora_Logo.svg new file mode 100644 index 0000000000000000000000000000000000000000..4fe142fbd434d0e84e7ed6578d4e4f2186f2245e --- /dev/null +++ b/examples/chatbot/html/img/Collabora_Logo.svg @@ -0,0 +1,3313 @@ + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 +qAxPWT/77trYbO5kSaZzt3NeHNXSH8793lLNIbPn+IRjr8f23xw7usYfMuts3cZ5Nutr6cf+YGvr +zDe2urFX0ietTkfNXnib26ssU6dO9b2p74M1o6qbnafuX9YJp163rZkO3UqH7imjPyDMoZPRib6V +6jT6d7Ru6mbE2aqXqd04WvbYtexafqJ0o4U51vFfeZq7ek6u17y0du5a9zqbF/5BXp2TZXqTVfPL +m9f/uj5Ln6Wmo8fvTpZRTRYpbQ4WTqnHrDbHstSUO4hjxdKaw/rtYN0OZh3mZJ1m2eYgEAEDggeM +LRxQUFA8KDPDmiuzGtuZrYt2Z8019zy1HfzZ2APbZmbe2KIOJmVphuixq5nS2Y5rUs/O5h7cpq0d +P1l0uDRlqjyzWbszxEmzMc3BVUUbzunh2dkVDXUyTe/wRp7SNb3vkO+6nkLP/ao4N8WxUdbgpF0H +9bfzqHlQ1aw6qjj2mrV1ZdKQt3YT/7knd/Jdzhp+XbPHj1Ut5xI1D9asoWct11DJp2hkS7/Uof2Q +zfedss+mypeTT1PZeDHJNuoDr87p5pS1cMr2KcIhvZuybX5arTHr3PVTzpOJqsZozMcxNWtiXjUf +7tp0zTVl0jpyzTNQ5tcEv46d7+5qfXtXe1eFpK+po8W7WwmonerZVdGvq9773nSh0Wh7FXnXnrNq +t69aVn1Jb7Hwv8Gj4vP5vPOam4+wmqo0mkejl7PXXN1c1VTNaz6v180d2vpf32te55oFBUWSsxVh +aXdBPfvVvaqqqu5V9aqqv978e7zz168+/+/X6582j4u7r7zeOL/4hcU73nc7/m4Lv4/od3v3n9Rf +3/5K/9ux/Wb3mm/32+r30l839fr4pysNne5fzbupmV593vPqPInpvcE0pg0mpjcTnd5c8FpaVuba +5o45EZ2VW5uVuUS7aGm5YFvpm8rCsc0kbSu3cm2xvIumpPQS5S4uLtZi2aIprqLi2KIa7qHNkGyF +eUtI59MdPa/P+/Oe9jZv7+7O8NZs7za9ePaZz67OzrYu87ze79J56bx0dLe+u909W3f3t79N561v +b/ue9m56bfSiveeau9NNFHFto9m8Y96r+VXr2tuyycku2chrJds8ZEu2NVsbq629lRmt3Wi/arWJ +qmZrRPWT5pSLVl3er9l8JlvVntW09pp0y7rrp67pLqipR3V3bgu/LeQtk0q0VEv9v7aGn11bQBqq +I5lstX1mPKeZz2Ws8lrBnOYFNDSvbbRRbUI7jT77zmvbtsnORj3nLaJTjYjoH9rHPE3rXPoubZ+i +0Wj0nc9rhbPRa4X0pc+avnfsu09ttfrUdZ46V1mdXd0d2hnt1s5URDy8u7z7pe/uzm6d57wf3nDy +sibvCifTeb+fb/9O925+98v/8mp96+HO6e2d7q3xjvDmiPDoztB2TZ3CI1xNDGv2dPTUu7eb6OnZ +HqVNawrXpmXz2rDQami4Vi/YnLYafbh4hIiIl4iINqKZIRpaD82MthFPx8z2ZocLh4e1N4iGmLim +WzwbjZZGUzSiFdoR7TqJqDbH41rBFEdxMcem5UpTUtpDSZmYe1p3anmnVbZISZS2Li4iZSZWUmYl +ljMTFcfoXLjkEvXyEjNtH8zDvI8xfUqFaZaGacml2WXOy0s7b3O2pTnNOqb2p+VawSyTXLm1ttpY +ZeVlZa4VMjFTk872XCuYpmna5q0Vyh4yq9Kqsi3btI+Z1a1u9S3X19b/JrqlbW5amtM1m5pJ9Luq +L+3UT0pjX/upET92q/lrxfFxfMwTjp9jq/21+TT3s4Vf/jR/+rn7fXMd/7586dVc3pW38cKO5U3P +yvCfyucrf82jld5TdcP5Sz+k6qqlfemJkJRKq1RLS5XMXJVjVlPT8Y2ZXm6eJlZ7Ht9aY/W1as5j +NTW11UhtUiLbmuK+9vvSfdnaY+bRm+JY1zev3mpqtf7u7lra5HR/pKc7I2rVWU/v7vAUdTfPhppz +mol5vW4NKirOVe9Kz1a1Nj+oqd7Lpw0v02RfnNOjsXd9eoi1d9xD697njmh7ePyu86vz1f2i7veO +LNMfXdRd1+jqnnruCP9LohtrUo97NKkLSDeI6FQkRCQ6/CQuIM3ReE2dPE3dw3vzSblVU1ZdW9Ep +qLnofPwV3XVSM38dnGvW88+6Ls2vaZqqN6uqurVIO1t0+xwtOqIXZlZmma4nHxQWnQJmjmuLjKrK +dLboqg6Hik6BqHaJbq1Epx5dOtHRqcyWY6KjD21aDW2dK090CruwSgnWUG19dkl1VXd0zWuztaur +e9/d1d21vP3k7s7i4CbuWpeUcJNbWyuv0dpWLY1tTdVebW0t0V5+amlpaZdqaVY1M1dNqZRlxkrd +MzrlDeIqqvVsak9Nq76VFnVMqS4hVa3v6uLps6he0l2toYRoiEgX8Vjo1fV6vdbfWQ== + + + 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 +0D9ToMrysUHGRzuu4WT1OqaO3RWFkR5xxvDm0Z4Sl2jC2TeKaElgfvve9jvRpCDSXuPRTdP3xaIC +m36wAoByIMoLc9eDB3A5LZRLVFgfA4ddw5pBb7ac1bZ/ZfSihi7hN7pp5ebgliY832dPzuv5gUQB +j+PEoHxRQP4NuvCXSeh9ndj6vvW/9QTBI0mOIea+RjDoKr5J12ece6s0JNZbxhMbkJCFKyYFfQyK +ogH5xHed7H9xAXz2z43+H7WYI/rN3O/ias0gNpUIQKdRLCm/ud6t/3zFZ+zeIy8zQyZzhQLujz5/ +97Pj/LOd7/y8uAFKwQgdKuBOaNQGjy0sn2tD6zqKxVsNHJZNvvTmB52htyVXdnfvIvLLEBlmcIKM +cYYBhgGPAXfL9zrmxvX2Kra39258fMfFxUJTxZrxotn2YsLaxlbnVi1qt2IrZiu3JiuzcmJu273l +w9tjZVZWjItrrWtTUVdNjdXYWq/1Ws24trV/vdeNa9qmasqNfV6vAkt5r4Gllam4VKQ1jsiJbFls +iZypiXuJCpeonMldCkTEvLu+2ztb5v86/ddgvv9+x+70UyByvnHt5r28tdayLUu4trloqv0q3u+3 +borp239/977v3dvq7erd7d3cZt3e3FzcymXsXOa91I2Li9vLycuMfLU/czPzsl7/f5f1ql8940+f +7qc/5dM746H2abLh91T7lNmemq7n97mTOZN5mXmTOTtzs5/Nz25+cnFydmdn55V2lpqWXTLNl6Z1 +6ZrebjLVU0vr1NRStVY9xb1VxdZLvUZVRb3r1dVbXVVYfafrNdfU1lC1elVRq71qmba19RrnLWZO +5kqurLzE3cjIjFWpsbmxu5sbu7qxsaqt0SxVVqWprqXlpsrOZPlUmdrS0rI5ORGz02WnauzLC8WM +x7qiXisl4t1PNd3r0tX5b1NmROVUr//8J/SF/Cd/a7/frb++Wqd1tdtL+fj/Ji6uZq7iOj7/17+l ++vu3sPDH+jlhZWl2MZZWbkpW1D/xb2UW/1h9////itP//Tan/P/3fvkYl3tVz73JubbF173ftt7u +VS793got9d5Kb3Wrurq6xv4VPvEeC7N0E3P9yPdaXee01fsf0VPgOlfd/8I/8T+BoHT9+67ExG1l +Womzy6Nlsnvapqo/gZa3T2jpEwgNw1I7GoKzCu58AqHBVYlEiQMKN7Nsa+z5FtusXpimd7rv7aq2 +p+p3qm6F6ve7G/X39fb1dePdetmXqu9M2NqNwEBQwLZO68bG8TWyMjmrshMREatyEw+PV2gD39jd +jdzX3NeK6sayu7uq7HMzc7+v39u3fdu3vd2lfdrv7e7G7u7+deZ512z51nyKay6zvGSXbMibfLzb +N+VW5EXmvs5ebGyF/bATsxu1WduyT++0FdtmeluF3cx015hN2awvqeH19hhxOQ0OA0UNGCACMAJA +IABZFg8DigUmYIBAAMIAAVqihkEgAQkaaCl1WfqEtt549wnEEO+292ad7PSv32Xun79TO77/Ok3+ +K+96+rXj3/l9WlxWbFzVie98d76l5vf9P07HT/xhptbDy8vk5/3yrnc0/l3hXd2l2ly0V7oqu1SV +hXiJWwHx/f7hDfvGhs39y0yLqz+iFqLlk1P+ldy/3MT93E2cv0SrM0vjdL+qxGqsyu6ExU80/ond +ipzI9/Sty0RLXF25qmmmpqmvqWuZExd/K2k9a6sri/XqWsXvVU3df6LqWvxb2qZlMl4TW6IZn6/4 +aX2dt+a91d7ePN5/X7n2Tsp73/fWlTVqGp9aZrKq2+ZMxoVthckK75lrfHVnVXzf46NeZZ8hv/dI +26/VdZrs+GqYym79pxm/9vZ1vEe494hVf4+8+ImulJXM13sELfkJM0a+63TGhGa32rreI6ZWqWyP +dCnvkeM/wb+q4id2O22X5ev9a/2dqutVnfjXm3/lLebnOVfNrsXXWt1K68TaugtHUcHhOARERIyS +PDxIggMlaRgWz9MwFs/TIPAsUqsgOIkapEqVhxBqzLtYoDsrKytboMYW/GgwFyT7YGkWZkEbnAR6 +EhYLlBAtzcM8SHgamIXDJCyPhiHBWRaoISFicTwYDGYhoQ6pS1CkNCJpHGgWCMYBR1k88OBpLJAh +hlhCHaKGJFQdUnUJakhdgiHGNA8Oh2EsC4dZiJLlYYF+CnbxQAdAC+5SsGAGNM+jAKHpKIqiKIop +CiuKKQorqgwMRCQWNAmURI4FumBZIEbTMAxdOI/zaDwUJXmiJ3JUw8LQeCBGsjhMs4DSJMoCPWAi +ZrFIkgbjJI1EBkMKgoGiZGFEFBDxQLM0aBbHSRwUIBAdx2APyQKRszQWJWkeHMyCowwJBgaHIWmY +RbIHs0igRRLR8DSPwwP0LJAWPIvEoUGzPFgMSIO4xcNAA7QsEC0Nh4iBEgfnIB1YOYiYBh2gg8V5 +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 +zyHTC2i5lOnV5Y2qA8lh5EJ+WGpQ7ldHQ3qxE1YIMpN1BH6bQIZCPmKi1WgzbISpaDXaDMNdF+1X +MRhUo82QPFCI9jRFULA/Sw4Q7AVKzyskmqFBTmEP4hYO2BNYbSIPKvR1Jm2GC83FDEcx4XpcKAQz +hpUFUxZa5mWq2AlZnvZtRx7oTlcgvbosijRYla8qTAUDkpZhRrGcCs6OhBbCpxUlgXUpIIEz6CYw +eXphEj48SSROT6RiZQMEV4DqGoxA1UBC6qaz1B0NtBmOEYPUFWkz1LGbWoGViyolXNBMd1oUizGg +XJE2w/GBUq4okrkSwKu6JRL5X/UIDMC7cJ1KCSeDzJ0LAIUCugNpnywYCxwbvAXaDLGMYEOGFpIt +GbQ6aMv+PXdr/GgT0fhoM2zYGyv8fCjW5WgzvOlGn8PRZviO28VyRtTFfjVcGdKLBTkHGERDgzEb +5+NErGz4CLAnw4KlSTtQiPZR0qLJXNXSqXzf99VXbHULgO1AV3jlbDvdKxcrvGKr22u3KrwAsNLF +au41C7DKFTQaKWiG+7ac2xJzXn6ZP1da2a/elvPMy0wp2Jkun3OLy1zP/2zfcs7x/2jLXLh23+cc +l7nQb99jWVsZY95LrsvM83N+ba6zqy3n93LMeU/7zpVWsJ9tbnGN92fcb3l1t5w/7hm/1v32Eufa +6rvv2zfHGPNbZ2XvGZdXX53L28vawv12vR+PZfn9dtw1x/w+bVcK7rmm+u1Y9vy75N/zzHaNS743 +x+O/7rnvbPloe64pL0uOdd6Z811ybXNNOS9zpb3NJf/O+d77O+c5c77LXFslH8ucc660+9t2Xt78 +nf/n2sqbW5tLznOutM055x3nzf+z7pxfe7HmeLQ4d257zuO2WVv8tM2tzunenffP9bxcd17mm3Xn +2uZsc6Vx3fm2GVbTWYp12fm1tp42l1jnXVt4c9z538w73jfrkdtcWzx3vm0u5Mflzbu2Cvi7zmO3 +GeerfyxtrrQyz3rW93u2uKYdY1xp3/fG+Hu2uFIKdvZ9X9651d9viW2ZObf5e8Y1xd85x5VWyK8/ +2+/fefld74utpuW3/TWG1XSW9bX9Ma5pwfaMa8o53rhSCiBGeW//a7m9uLbKXehlzm+77fzt/99u +Oa60fR/fMufW50Lne9Sfbcef7etue9640nj/2/nO6c52c461viP/+2W6c7+7l+XGeA== + + + 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 + + + diff --git a/examples/chatbot/html/img/Phi.svg b/examples/chatbot/html/img/Phi.svg new file mode 100644 index 0000000000000000000000000000000000000000..ee1c12f95bdc32a4b62001d8aa078e3554a02b01 --- /dev/null +++ b/examples/chatbot/html/img/Phi.svg @@ -0,0 +1,14 @@ + + + + +]> + + + + + diff --git a/examples/chatbot/html/img/microphone-hover.png b/examples/chatbot/html/img/microphone-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..e249ce391068843b882c65a3be0daa2cdd1eebaf Binary files /dev/null and b/examples/chatbot/html/img/microphone-hover.png differ diff --git a/examples/chatbot/html/img/microphone-white.png b/examples/chatbot/html/img/microphone-white.png new file mode 100644 index 0000000000000000000000000000000000000000..0fa54263785ac85ae1d71397ac5da230fe1e4dd8 Binary files /dev/null and b/examples/chatbot/html/img/microphone-white.png differ diff --git a/examples/chatbot/html/img/microphone.png b/examples/chatbot/html/img/microphone.png new file mode 100644 index 0000000000000000000000000000000000000000..67389ac3def9a48c41cbf261ebeba0c15319165e Binary files /dev/null and b/examples/chatbot/html/img/microphone.png differ diff --git a/examples/chatbot/html/img/pause.png b/examples/chatbot/html/img/pause.png new file mode 100644 index 0000000000000000000000000000000000000000..64add91783232bcece123d633b235c85d62cb33c Binary files /dev/null and b/examples/chatbot/html/img/pause.png differ diff --git a/examples/chatbot/html/img/record.png b/examples/chatbot/html/img/record.png new file mode 100644 index 0000000000000000000000000000000000000000..dadb556341d846a466c40b57d4be00f73a14acd0 Binary files /dev/null and b/examples/chatbot/html/img/record.png differ diff --git a/examples/chatbot/html/img/stop.png b/examples/chatbot/html/img/stop.png new file mode 100644 index 0000000000000000000000000000000000000000..1b297ff16a92e9368c4b8d60a2de81ecd0af83c0 Binary files /dev/null and b/examples/chatbot/html/img/stop.png differ diff --git a/examples/chatbot/html/index.html b/examples/chatbot/html/index.html new file mode 100644 index 0000000000000000000000000000000000000000..b3f34270d44615704ed294a766d9c73082931748 --- /dev/null +++ b/examples/chatbot/html/index.html @@ -0,0 +1,52 @@ + + + + + + Collabora - WhisperFusion: The Power of WhisperLive, LLM's, and WhisperSpeech + + + + +
+
+
+ +
+
+

WhisperFusion: The Power of WhisperLive, LLM's, and WhisperSpeech

+
+

Using state-of-the-art natural language processing techniques, we implemented WhisperFusion a techonlogy demo that combines live transcriptions, LLM's and text-to-speech, in a low-latency pipeline. For more details about the demo, checkout https://github.com/collabora/WhisperFusion.

+
+
+
+
+ +

+
+
+ +
+
+ +
+
+
Click the microphone to start
+
+
+ +
+ +
+ +
+
+
+

+
+ + + + + diff --git a/examples/chatbot/html/js/audio-processor.js b/examples/chatbot/html/js/audio-processor.js new file mode 100644 index 0000000000000000000000000000000000000000..3697e69110ba345ddf76832fc7f0e62ce379aed2 --- /dev/null +++ b/examples/chatbot/html/js/audio-processor.js @@ -0,0 +1,31 @@ +class AudioStreamProcessor extends AudioWorkletProcessor { + constructor() { + super(); + this.chunkSize = 4096; + this.buffer = new Float32Array(this.chunkSize); + this.bufferPointer = 0; + } + + process(inputs, outputs, parameters) { + const input = inputs[0]; + const output = outputs[0]; + + for (let i = 0; i < input[0].length; i++) { + this.buffer[this.bufferPointer++] = input[0][i]; + + if (this.bufferPointer >= this.chunkSize) { + + this.port.postMessage(this.buffer); + this.bufferPointer = 0; + } + } + + for (let channel = 0; channel < input.length; ++channel) { + output[channel].set(input[channel]); + } + + return true; + } +} + +registerProcessor("audio-stream-processor", AudioStreamProcessor); \ No newline at end of file diff --git a/examples/chatbot/html/js/main.js b/examples/chatbot/html/js/main.js new file mode 100644 index 0000000000000000000000000000000000000000..623115b03144d7ad93ef0b4fcd189412c243c509 --- /dev/null +++ b/examples/chatbot/html/js/main.js @@ -0,0 +1,340 @@ +let websocket_uri = 'ws://localhost:6006'; +let websocket_audio_uri = 'ws://localhost:8888'; + +let bufferSize = 4096, + AudioContext, + context, + processor, + input, + websocket; +var intervalFunction = null; +var recordingTime = 0; +var server_state = 0; +var websocket_audio = null; +let audioContext_tts = null; +var you_name = "Marcus" + +var audioContext = null; +var audioWorkletNode = null; +var audio_state = 0; +var available_transcription_elements = 0; +var available_llm_elements = 0; +var available_audio_elements = 0; +var llm_outputs = []; +var new_transcription_element_state = true; +var audio_sources = []; +var audio_source = null; + +initWebSocket(); + +const zeroPad = (num, places) => String(num).padStart(places, '0') + +const generateUUID = () => { + let dt = new Date().getTime(); + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { + const r = (dt + Math.random() * 16) % 16 | 0; + dt = Math.floor(dt / 16); + return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16); + }); +}; + +function recording_timer() { + recordingTime++; + document.getElementById("recording-time").innerHTML = zeroPad(parseInt(recordingTime / 60), 2) + ":" + zeroPad(parseInt(recordingTime % 60), 2) + "s"; +} + +const start_recording = async () => { + console.log(audioContext) + try { + if (audioContext) { + + await audioContext.resume(); + + const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); + + if (!audioContext) return; + console.log(audioContext?.state); + + await audioContext.audioWorklet.addModule("js/audio-processor.js"); + + const source = audioContext.createMediaStreamSource(stream); + audioWorkletNode = new AudioWorkletNode(audioContext, "audio-stream-processor"); + + audioWorkletNode.port.onmessage = (event) => { + if (server_state != 1) { + console.log("server is not ready!!") + return; + } + const audioData = event.data; + if (websocket && websocket.readyState === WebSocket.OPEN && audio_state == 0) { + websocket.send(audioData.buffer); + console.log("send data") + } + }; + + source.connect(audioWorkletNode); + } + } catch (e) { + console.log("Error", e); + } +}; + +const handleStartRecording = async () => { + start_recording(); +}; + +const startRecording = async () => { + document.getElementById("instructions-text").style.display = "none"; + document.getElementById("control-container").style.backgroundColor = "white"; + + AudioContext = window.AudioContext || window.webkitAudioContext; + audioContext = new AudioContext({ latencyHint: 'interactive', sampleRate: 16000 }); + + audioContext_tts = new AudioContext({ sampleRate: 24000 }); + + document.getElementById("recording-stop-btn").style.display = "block"; + document.getElementById("recording-dot").style.display = "block"; + document.getElementById("recording-line").style.display = "block"; + document.getElementById("recording-time").style.display = "block"; + + intervalFunction = setInterval(recording_timer, 1000); + + await handleStartRecording(); +}; + +function stopRecording() { + audio_state = 1; + clearInterval(intervalFunction); +} + +function initWebSocket() { + websocket_audio = new WebSocket(websocket_audio_uri); + websocket_audio.binaryType = "arraybuffer"; + + websocket_audio.onopen = function() { } + websocket_audio.onclose = function(e) { } + websocket_audio.onmessage = function(e) { + available_audio_elements++; + + let float32Array = new Float32Array(e.data); + let audioBuffer = audioContext_tts.createBuffer(1, float32Array.length, 24000); + audioBuffer.getChannelData(0).set(float32Array); + + new_whisper_speech_audio_element("audio-" + available_audio_elements, Math.floor(audioBuffer.duration)); + + audio_sources.push(audioBuffer); + + audio_source = audioContext_tts.createBufferSource(); + audio_source.buffer = audioBuffer; + audio_source.connect(audioContext_tts.destination); + audio_source.start(); + + window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }); + } + + websocket = new WebSocket(websocket_uri); + websocket.binaryType = "arraybuffer"; + + console.log("Websocket created."); + + websocket.onopen = function() { + console.log("Connected to server."); + + websocket.send(JSON.stringify({ + uid: generateUUID(), + multilingual: false, + language: "en", + task: "transcribe" + })); + } + + websocket.onclose = function(e) { + console.log("Connection closed (" + e.code + ")."); + } + + websocket.onmessage = function(e) { + var data = JSON.parse(e.data); + + if ("message" in data) { + if (data["message"] == "SERVER_READY") { + server_state = 1; + } + } else if ("segments" in data) { + if (new_transcription_element_state) { + available_transcription_elements = available_transcription_elements + 1; + + var img_src = "0.png"; + if (you_name.toLowerCase() == "marcus") { + you_name = "Marcus"; + img_src = "0.png"; + } else if (you_name.toLowerCase() == "vineet") { + you_name = "Vineet"; + img_src = "1.png"; + } else if (you_name.toLowerCase() == "jakub") { + you_name = "Jakub"; + img_src = "2.png"; + } + + new_transcription_element(you_name, img_src); + new_text_element("

" + data["segments"][0].text + "

", "transcription-" + available_transcription_elements); + new_transcription_element_state = false; + } + document.getElementById("transcription-" + available_transcription_elements).innerHTML = "

" + data["segments"][0].text + "

"; + + if (data["eos"] == true) { + new_transcription_element_state = true; + } + } else if ("llm_output" in data) { + new_transcription_element("Phi-2", "Phi.svg"); + new_text_element("

" + data["llm_output"][0] + "

", "llm-" + available_transcription_elements); + } + + window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }); + } +} + +function new_transcription_element(speaker_name, speaker_avatar) { + var avatar_container = document.createElement("div"); + avatar_container.className = "avatar-container"; + + var avatar_img = document.createElement("div"); + avatar_img.innerHTML = ""; + + var avatar_name = document.createElement("div"); + avatar_name.className = "avatar-name"; + avatar_name.innerHTML = speaker_name; + + var dummy_element = document.createElement("div"); + + avatar_container.appendChild(avatar_img); + avatar_container.appendChild(avatar_name); + avatar_container.appendChild(dummy_element); + + document.getElementById("main-wrapper").appendChild(avatar_container); +} + +function new_text_element(text, id) { + var text_container = document.createElement("div"); + text_container.className = "text-container"; + text_container.style.maxWidth = "500px"; + + var text_element = document.createElement("div"); + text_element.id = id; + text_element.innerHTML = "

" + text + "

"; + + var dummy_element = document.createElement("div"); + + text_container.appendChild(text_element); + text_container.appendChild(dummy_element); + + document.getElementById("main-wrapper").appendChild(text_container); +} + +function new_transcription_time_element(time) { + var text_container = document.createElement("div"); + text_container.className = "transcription-timing-container"; + text_container.style.maxWidth = "500px"; + + var text_element = document.createElement("div"); + text_element.innerHTML = "WhisperLive - Transcription time: " + time + "ms"; + + var dummy_element = document.createElement("div"); + + text_container.appendChild(text_element); + text_container.appendChild(dummy_element); + + document.getElementById("main-wrapper").appendChild(text_container); +} + +function new_llm_time_element(time) { + var text_container = document.createElement("div"); + text_container.className = "llm-timing-container"; + text_container.style.maxWidth = "500px"; + + var first_response_text_element = document.createElement("div"); + first_response_text_element.innerHTML = "Phi-2 first response time: " + time + "ms"; + + var complete_response_text_element = document.createElement("div"); + complete_response_text_element.innerHTML = "Phi-2 complete response time: " + time + "ms"; + + var dummy_element = document.createElement("div"); + + text_container.appendChild(first_response_text_element); + text_container.appendChild(complete_response_text_element); + text_container.appendChild(dummy_element); + + document.getElementById("main-wrapper").appendChild(text_container); +} + +function new_whisper_speech_audio_element(id, duration) { + var audio_container = document.createElement("div"); + audio_container.className = "whisperspeech-audio-container"; + audio_container.style.maxWidth = "500px"; + + var audio_div_element = document.createElement("div"); + var audio_element = document.createElement("audio"); + audio_element.style.paddingTop = "20px"; + + if (duration > 10) + duration = 10; + audio_element.src = "static/" + duration + ".mp3"; + + audio_element.id = id; + audio_element.onplay = function() { + console.log(this.id) + var id = this.id.split("-")[1] - 1; + + if (audio_source) { + audio_source.disconnect(); + } + + audio_source = audioContext_tts.createBufferSource(); + audio_source.buffer = audio_sources[id]; + audio_source.connect(audioContext_tts.destination); + audio_source.start() + }; + audio_element.onpause = function() { + this.currentTime = 0; + console.log(this.id) + var id = this.id.split("-")[1] - 1; + if (audio_source) { + audio_source.stop(); + } + }; + audio_element.controls = true; + + audio_div_element.appendChild(audio_element); + + var dummy_element_a = document.createElement("div"); + var dummy_element_b = document.createElement("div"); + + audio_container.appendChild(dummy_element_a); + audio_container.appendChild(audio_div_element); + audio_container.appendChild(dummy_element_b); + + document.getElementById("main-wrapper").appendChild(audio_container); +} + +function new_whisper_speech_time_element(time) { + var text_container = document.createElement("div"); + text_container.className = "whisperspeech-timing-container"; + text_container.style.maxWidth = "500px"; + + var text_element = document.createElement("div"); + text_element.innerHTML = "WhisperSpeech response time: " + time + "ms"; + + var dummy_element = document.createElement("div"); + + text_container.appendChild(text_element); + text_container.appendChild(dummy_element); + + document.getElementById("main-wrapper").appendChild(text_container); +} + +document.addEventListener('DOMContentLoaded', function() { + const queryString = window.location.search; + const urlParams = new URLSearchParams(queryString); + if (urlParams.has('name')) { + you_name = urlParams.get('name') + } + }, false); \ No newline at end of file diff --git a/examples/chatbot/html/static/0.mp3 b/examples/chatbot/html/static/0.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..787be87653c143603c96d4327290dedd054b09e1 Binary files /dev/null and b/examples/chatbot/html/static/0.mp3 differ diff --git a/examples/chatbot/html/static/1.mp3 b/examples/chatbot/html/static/1.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..d00f3c41dc160269d38ea6e34fdd8794e6c93008 Binary files /dev/null and b/examples/chatbot/html/static/1.mp3 differ diff --git a/examples/chatbot/html/static/10.mp3 b/examples/chatbot/html/static/10.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..2249cae9a3510a0cb2229a5e733ebc24d3a4acb0 Binary files /dev/null and b/examples/chatbot/html/static/10.mp3 differ diff --git a/examples/chatbot/html/static/2.mp3 b/examples/chatbot/html/static/2.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..0766cc95eb0ed79639f0cea68d765c1f1d196586 Binary files /dev/null and b/examples/chatbot/html/static/2.mp3 differ diff --git a/examples/chatbot/html/static/3.mp3 b/examples/chatbot/html/static/3.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..2060864853559ed9f90ae278a6a1c8ab9300b5c9 Binary files /dev/null and b/examples/chatbot/html/static/3.mp3 differ diff --git a/examples/chatbot/html/static/4.mp3 b/examples/chatbot/html/static/4.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..00c976f0b64804e597f07a015ace360b8073a371 Binary files /dev/null and b/examples/chatbot/html/static/4.mp3 differ diff --git a/examples/chatbot/html/static/5.mp3 b/examples/chatbot/html/static/5.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..cad47f7684b09997ac3096857c4b187634865551 Binary files /dev/null and b/examples/chatbot/html/static/5.mp3 differ diff --git a/examples/chatbot/html/static/6.mp3 b/examples/chatbot/html/static/6.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..43d837c2f6b2850d176f19aa3bb78acb694ccfdd Binary files /dev/null and b/examples/chatbot/html/static/6.mp3 differ diff --git a/examples/chatbot/html/static/7.mp3 b/examples/chatbot/html/static/7.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..e47e161af954f24813333fd81ec54d4c8286396a Binary files /dev/null and b/examples/chatbot/html/static/7.mp3 differ diff --git a/examples/chatbot/html/static/8.mp3 b/examples/chatbot/html/static/8.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..38fb7b8a00f0c209d798056e8bddc8b0945043b1 Binary files /dev/null and b/examples/chatbot/html/static/8.mp3 differ diff --git a/examples/chatbot/html/static/9.mp3 b/examples/chatbot/html/static/9.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..2249cae9a3510a0cb2229a5e733ebc24d3a4acb0 Binary files /dev/null and b/examples/chatbot/html/static/9.mp3 differ diff --git a/llm_service.py b/llm_service.py new file mode 100644 index 0000000000000000000000000000000000000000..3db1fa317261fae82c6144239f3f7048a3477ff9 --- /dev/null +++ b/llm_service.py @@ -0,0 +1,354 @@ +import time +import json +from pathlib import Path +from typing import Optional + +import logging +logging.basicConfig(level = logging.INFO) + +import numpy as np +import torch +from transformers import AutoTokenizer +import re + +import tensorrt_llm +from tensorrt_llm.logger import logger +from tensorrt_llm.runtime import PYTHON_BINDINGS, ModelRunner + +if PYTHON_BINDINGS: + from tensorrt_llm.runtime import ModelRunnerCpp + + +def read_model_name(engine_dir: str): + engine_version = tensorrt_llm.runtime.engine.get_engine_version(engine_dir) + + with open(Path(engine_dir) / "config.json", 'r') as f: + config = json.load(f) + + if engine_version is None: + return config['builder_config']['name'] + + return config['pretrained_config']['architecture'] + + +def throttle_generator(generator, stream_interval): + for i, out in enumerate(generator): + if not i % stream_interval: + yield out + + if i % stream_interval: + yield out + + +def load_tokenizer(tokenizer_dir: Optional[str] = None, + vocab_file: Optional[str] = None, + model_name: str = 'gpt', + tokenizer_type: Optional[str] = None): + if vocab_file is None: + use_fast = True + if tokenizer_type is not None and tokenizer_type == "llama": + use_fast = False + # Should set both padding_side and truncation_side to be 'left' + tokenizer = AutoTokenizer.from_pretrained(tokenizer_dir, + legacy=False, + padding_side='left', + truncation_side='left', + trust_remote_code=True, + tokenizer_type=tokenizer_type, + use_fast=use_fast) + else: + # For gpt-next, directly load from tokenizer.model + assert model_name == 'gpt' + tokenizer = T5Tokenizer(vocab_file=vocab_file, + padding_side='left', + truncation_side='left') + + if model_name == 'qwen': + with open(Path(tokenizer_dir) / "generation_config.json") as f: + gen_config = json.load(f) + chat_format = gen_config['chat_format'] + if chat_format == 'raw': + pad_id = gen_config['pad_token_id'] + end_id = gen_config['eos_token_id'] + elif chat_format == 'chatml': + pad_id = tokenizer.im_end_id + end_id = tokenizer.im_end_id + else: + raise Exception(f"unknown chat format: {chat_format}") + elif model_name == 'glm_10b': + pad_id = tokenizer.pad_token_id + end_id = tokenizer.eop_token_id + else: + if tokenizer.pad_token_id is None: + tokenizer.pad_token_id = tokenizer.eos_token_id + pad_id = tokenizer.pad_token_id + end_id = tokenizer.eos_token_id + + return tokenizer, pad_id, end_id + + +class TensorRTLLMEngine: + def __init__(self): + pass + + def initialize_model(self, engine_dir, tokenizer_dir): + self.log_level = 'error' + self.runtime_rank = tensorrt_llm.mpi_rank() + logger.set_level(self.log_level) + model_name = read_model_name(engine_dir) + self.tokenizer, self.pad_id, self.end_id = load_tokenizer( + tokenizer_dir=tokenizer_dir, + vocab_file=None, + model_name=model_name, + tokenizer_type=None, + ) + self.prompt_template = None + self.runner_cls = ModelRunner + self.runner_kwargs = dict(engine_dir=engine_dir, + lora_dir=None, + rank=self.runtime_rank, + debug_mode=False, + lora_ckpt_source='hf') + self.runner = self.runner_cls.from_dir(**self.runner_kwargs) + self.last_prompt = None + self.last_output = None + + def parse_input( + self, + input_text=None, + add_special_tokens=True, + max_input_length=923, + pad_id=None, + ): + if self.pad_id is None: + self.pad_id = self.tokenizer.pad_token_id + + batch_input_ids = [] + for curr_text in input_text: + if self.prompt_template is not None: + curr_text = self.prompt_template.format(input_text=curr_text) + input_ids = self.tokenizer.encode( + curr_text, + add_special_tokens=add_special_tokens, + truncation=True, + max_length=max_input_length + ) + batch_input_ids.append(input_ids) + + batch_input_ids = [ + torch.tensor(x, dtype=torch.int32) for x in batch_input_ids + ] + return batch_input_ids + + def decode_tokens( + self, + output_ids, + input_lengths, + sequence_lengths, + transcription_queue + ): + batch_size, num_beams, _ = output_ids.size() + for batch_idx in range(batch_size): + if transcription_queue.qsize() != 0: + return None + + inputs = output_ids[batch_idx][0][:input_lengths[batch_idx]].tolist() + input_text = self.tokenizer.decode(inputs) + output = [] + for beam in range(num_beams): + if transcription_queue.qsize() != 0: + return None + + output_begin = input_lengths[batch_idx] + output_end = sequence_lengths[batch_idx][beam] + outputs = output_ids[batch_idx][beam][ + output_begin:output_end].tolist() + output_text = self.tokenizer.decode(outputs) + output.append(output_text) + return output + + def format_prompt_qa(self, prompt, conversation_history): + formatted_prompt = "" + for user_prompt, llm_response in conversation_history: + formatted_prompt += f"Instruct: {user_prompt}\nOutput:{llm_response}\n" + return f"{formatted_prompt}Instruct: {prompt}\nOutput:" + + def format_prompt_chat(self, prompt, conversation_history): + formatted_prompt = "" + for user_prompt, llm_response in conversation_history: + formatted_prompt += f"Alice: {user_prompt}\nBob:{llm_response}\n" + return f"{formatted_prompt}Alice: {prompt}\nBob:" + + def format_prompt_chatml(self, prompt, conversation_history, system_prompt=""): + formatted_prompt = ("<|im_start|>system\n" + system_prompt + "<|im_end|>\n") + for user_prompt, llm_response in conversation_history: + formatted_prompt += f"<|im_start|>user\n{user_prompt}<|im_end|>\n" + formatted_prompt += f"<|im_start|>assistant\n{llm_response}<|im_end|>\n" + formatted_prompt += f"<|im_start|>user\n{prompt}<|im_end|>\n" + return formatted_prompt + + def run( + self, + model_path, + tokenizer_path, + transcription_queue=None, + llm_queue=None, + audio_queue=None, + input_text=None, + max_output_len=50, + max_attention_window_size=4096, + num_beams=1, + streaming=False, + streaming_interval=4, + debug=False, + ): + self.initialize_model( + model_path, + tokenizer_path, + ) + + logging.info("[LLM INFO:] Loaded LLM TensorRT Engine.") + + conversation_history = {} + + while True: + + # Get the last transcription output from the queue + transcription_output = transcription_queue.get() + if transcription_queue.qsize() != 0: + continue + + if transcription_output["uid"] not in conversation_history: + conversation_history[transcription_output["uid"]] = [] + + prompt = transcription_output['prompt'].strip() + + # if prompt is same but EOS is True, we need that to send outputs to websockets + if self.last_prompt == prompt: + if self.last_output is not None and transcription_output["eos"]: + self.eos = transcription_output["eos"] + llm_queue.put({ + "uid": transcription_output["uid"], + "llm_output": self.last_output, + "eos": self.eos, + "latency": self.infer_time + }) + audio_queue.put({"llm_output": self.last_output, "eos": self.eos}) + conversation_history[transcription_output["uid"]].append( + (transcription_output['prompt'].strip(), self.last_output[0].strip()) + ) + continue + + # input_text=[self.format_prompt_qa(prompt, conversation_history[transcription_output["uid"]])] + input_text=[self.format_prompt_chatml(prompt, conversation_history[transcription_output["uid"]], system_prompt="You are Dolphin, a helpful AI assistant")] + + self.eos = transcription_output["eos"] + + batch_input_ids = self.parse_input( + input_text=input_text, + add_special_tokens=True, + max_input_length=923, + pad_id=None, + ) + + input_lengths = [x.size(0) for x in batch_input_ids] + + logging.info(f"[LLM INFO:] Running LLM Inference with WhisperLive prompt: {prompt}, eos: {self.eos}") + start = time.time() + with torch.no_grad(): + outputs = self.runner.generate( + batch_input_ids, + max_new_tokens=max_output_len, + max_attention_window_size=max_attention_window_size, + end_id=self.end_id, + pad_id=self.pad_id, + temperature=1.0, + top_k=1, + top_p=0.0, + num_beams=num_beams, + length_penalty=1.0, + repetition_penalty=1.0, + stop_words_list=None, + bad_words_list=None, + lora_uids=None, + prompt_table_path=None, + prompt_tasks=None, + streaming=streaming, + output_sequence_lengths=True, + return_dict=True) + torch.cuda.synchronize() + if streaming: + for curr_outputs in throttle_generator(outputs, streaming_interval): + output_ids = curr_outputs['output_ids'] + sequence_lengths = curr_outputs['sequence_lengths'] + output = self.decode_tokens( + output_ids, + input_lengths, + sequence_lengths, + transcription_queue + ) + + if output is None: + break + + # Interrupted by transcription queue + if output is None: + continue + else: + output_ids = outputs['output_ids'] + sequence_lengths = outputs['sequence_lengths'] + context_logits = None + generation_logits = None + if self.runner.gather_context_logits: + context_logits = outputs['context_logits'] + if self.runner.gather_generation_logits: + generation_logits = outputs['generation_logits'] + output = self.decode_tokens( + output_ids, + input_lengths, + sequence_lengths, + transcription_queue + ) + self.infer_time = time.time() - start + + # if self.eos: + if output is not None: + output[0] = clean_llm_output(output[0]) + self.last_output = output + self.last_prompt = prompt + llm_queue.put({ + "uid": transcription_output["uid"], + "llm_output": output, + "eos": self.eos, + "latency": self.infer_time + }) + audio_queue.put({"llm_output": output, "eos": self.eos}) + logging.info(f"[LLM INFO:] Output: {output[0]}\nLLM inference done in {self.infer_time} ms\n\n") + + if self.eos: + conversation_history[transcription_output["uid"]].append( + (transcription_output['prompt'].strip(), output[0].strip()) + ) + self.last_prompt = None + self.last_output = None + +def clean_llm_output(output): + output = output.replace("\n\nDolphin\n\n", "") + output = output.replace("\nDolphin\n\n", "") + output = output.replace("Dolphin: ", "") + output = output.replace("Assistant: ", "") + + if not output.endswith('.') and not output.endswith('?') and not output.endswith('!'): + last_punct = output.rfind('.') + last_q = output.rfind('?') + if last_q > last_punct: + last_punct = last_q + + last_ex = output.rfind('!') + if last_ex > last_punct: + last_punct = last_ex + + if last_punct > 0: + output = output[:last_punct+1] + + return output diff --git a/main.py b/main.py new file mode 100644 index 0000000000000000000000000000000000000000..f4a5732cb0d173809eb05aa16050a7fcf27382a3 --- /dev/null +++ b/main.py @@ -0,0 +1,114 @@ +import multiprocessing +import argparse +import threading +import ssl +import time +import sys +import functools + +from multiprocessing import Process, Manager, Value, Queue + +from whisper_live.trt_server import TranscriptionServer +from llm_service import TensorRTLLMEngine +from tts_service import WhisperSpeechTTS + + +def parse_arguments(): + parser = argparse.ArgumentParser() + parser.add_argument('--whisper_tensorrt_path', + type=str, + default="/root/TensorRT-LLM/examples/whisper/whisper_small_en", + help='Whisper TensorRT model path') + parser.add_argument('--mistral', + action="store_true", + help='Mistral') + parser.add_argument('--mistral_tensorrt_path', + type=str, + default=None, + help='Mistral TensorRT model path') + parser.add_argument('--mistral_tokenizer_path', + type=str, + default="teknium/OpenHermes-2.5-Mistral-7B", + help='Mistral TensorRT model path') + parser.add_argument('--phi', + action="store_true", + help='Phi') + parser.add_argument('--phi_tensorrt_path', + type=str, + default="/root/TensorRT-LLM/examples/phi/phi_engine", + help='Phi TensorRT model path') + parser.add_argument('--phi_tokenizer_path', + type=str, + default="/root/TensorRT-LLM/examples/phi/phi-2", + help='Phi Tokenizer path') + return parser.parse_args() + + +if __name__ == "__main__": + args = parse_arguments() + if not args.whisper_tensorrt_path: + raise ValueError("Please provide whisper_tensorrt_path to run the pipeline.") + import sys + sys.exit(0) + + if args.mistral: + if not args.mistral_tensorrt_path or not args.mistral_tokenizer_path: + raise ValueError("Please provide mistral_tensorrt_path and mistral_tokenizer_path to run the pipeline.") + import sys + sys.exit(0) + + if args.phi: + if not args.phi_tensorrt_path or not args.phi_tokenizer_path: + raise ValueError("Please provide phi_tensorrt_path and phi_tokenizer_path to run the pipeline.") + import sys + sys.exit(0) + + multiprocessing.set_start_method('spawn') + + lock = multiprocessing.Lock() + + manager = Manager() + shared_output = manager.list() + + transcription_queue = Queue() + llm_queue = Queue() + audio_queue = Queue() + + + whisper_server = TranscriptionServer() + whisper_process = multiprocessing.Process( + target=whisper_server.run, + args=( + "0.0.0.0", + 6006, + transcription_queue, + llm_queue, + args.whisper_tensorrt_path + ) + ) + whisper_process.start() + + llm_provider = TensorRTLLMEngine() + # llm_provider = MistralTensorRTLLMProvider() + llm_process = multiprocessing.Process( + target=llm_provider.run, + args=( + # args.mistral_tensorrt_path, + # args.mistral_tokenizer_path, + args.phi_tensorrt_path, + args.phi_tokenizer_path, + transcription_queue, + llm_queue, + audio_queue, + ) + ) + llm_process.start() + + # audio process + tts_runner = WhisperSpeechTTS() + tts_process = multiprocessing.Process(target=tts_runner.run, args=("0.0.0.0", 8888, audio_queue)) + tts_process.start() + + llm_process.join() + whisper_process.join() + tts_process.join() diff --git a/publish.sh b/publish.sh new file mode 100644 index 0000000000000000000000000000000000000000..fb3334dbde064ecae59ad05ba84db0c6f2d0be5a --- /dev/null +++ b/publish.sh @@ -0,0 +1,4 @@ +#!/bin/bash -e + +docker push ghcr.io/collabora/whisperfusion-base:latest +docker push ghcr.io/collabora/whisperfusion:latest diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..5901f7cec6e1d8c522d4c2b42373428fcaa35279 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,12 @@ +faster-whisper==0.9.0 +websockets +onnxruntime==1.16.0 +ffmpeg-python +scipy +websocket-client +tiktoken==0.3.3 +kaldialign +braceexpand +openai-whisper +whisperspeech +soundfile diff --git a/run-whisperfusion.sh b/run-whisperfusion.sh new file mode 100644 index 0000000000000000000000000000000000000000..86f0c64d166af5695e74220bddc71636996c1502 --- /dev/null +++ b/run-whisperfusion.sh @@ -0,0 +1,16 @@ +#!/bin/bash -e + +test -f /etc/shinit_v2 && source /etc/shinit_v2 + +cd WhisperFusion +if [ "$1" != "mistral" ]; then + exec python3 main.py --phi \ + --whisper_tensorrt_path /root/whisper_small_en \ + --phi_tensorrt_path /root/dolphin-2_6-phi-2 \ + --phi_tokenizer_path /root/dolphin-2_6-phi-2/tokenizer +else + exec python3 main.py --mistral \ + --whisper_tensorrt_path /root/models/whisper_small_en \ + --mistral_tensorrt_path /root/models/mistral \ + --mistral_tokenizer_path teknium/OpenHermes-2.5-Mistral-7B +fi diff --git a/run_client.py b/run_client.py new file mode 100644 index 0000000000000000000000000000000000000000..b114ffbad6b1a6258b6793bbbd0d56aca0d5c794 --- /dev/null +++ b/run_client.py @@ -0,0 +1,7 @@ +from whisper_live.client import TranscriptionClient + +if __name__ == "__main__": + client = TranscriptionClient( + "0.0.0.0", "6006", is_multilingual=False, lang="en", translate=False + ) + client() # uses microphone audio \ No newline at end of file diff --git a/run_faster_whisper_server.py b/run_faster_whisper_server.py new file mode 100644 index 0000000000000000000000000000000000000000..281fe5ded8bc152d0cf0a2c3f3a1cf19a85147a6 --- /dev/null +++ b/run_faster_whisper_server.py @@ -0,0 +1,5 @@ +from whisper_live.server import TranscriptionServer + +if __name__ == "__main__": + server = TranscriptionServer() + server.run("0.0.0.0", 6006) \ No newline at end of file diff --git a/run_trt_server.py b/run_trt_server.py new file mode 100644 index 0000000000000000000000000000000000000000..24bfc49445c3ad77e68dbb0543888c95e03a6a13 --- /dev/null +++ b/run_trt_server.py @@ -0,0 +1,5 @@ +from whisper_live.trt_server import TranscriptionServer + +if __name__ == "__main__": + server = TranscriptionServer() + server.run("0.0.0.0", 6006) \ No newline at end of file diff --git a/setup-whisperfusion.sh b/setup-whisperfusion.sh new file mode 100644 index 0000000000000000000000000000000000000000..154d123ddf0ad397189154c13be9db7f6fc31e1d --- /dev/null +++ b/setup-whisperfusion.sh @@ -0,0 +1,27 @@ +#!/bin/bash -e + +## Clone this repo and install requirements +[ -d "WhisperFusion" ] || git clone https://github.com/collabora/WhisperFusion.git + +cd WhisperFusion +apt update +apt install ffmpeg portaudio19-dev -y + +## Install torchaudio matching the PyTorch from the base image +pip install --extra-index-url https://download.pytorch.org/whl/cu121 torchaudio + +## Install all the other dependencies normally +pip install -r requirements.txt + +## force update huggingface_hub (tokenizers 0.14.1 spuriously require and ancient <=0.18 version) +pip install -U huggingface_hub + +huggingface-cli download collabora/whisperspeech t2s-small-en+pl.model s2a-q4-tiny-en+pl.model +huggingface-cli download charactr/vocos-encodec-24khz + +mkdir -p /root/.cache/torch/hub/checkpoints/ +curl -L -o /root/.cache/torch/hub/checkpoints/encodec_24khz-d7cc33bc.th https://dl.fbaipublicfiles.com/encodec/v0/encodec_24khz-d7cc33bc.th +mkdir -p /root/.cache/whisper-live/ +curl -L -o /root/.cache/whisper-live/silero_vad.onnx https://github.com/snakers4/silero-vad/raw/master/files/silero_vad.onnx + +python -c 'from transformers.utils.hub import move_cache; move_cache()' diff --git a/setup.sh b/setup.sh new file mode 100644 index 0000000000000000000000000000000000000000..82648560c7db44568d2acf3b8d2ef7335cfbc586 --- /dev/null +++ b/setup.sh @@ -0,0 +1,6 @@ +#!/bin/bash -e + +./setup-whisper.sh +#./setup-mistral.sh +./setup-phi-2.sh +./setup-whisperfusion.sh diff --git a/tts_service.py b/tts_service.py new file mode 100644 index 0000000000000000000000000000000000000000..436b7ba327b1c7b7c23b2b9bcc821d22cf06d7a3 --- /dev/null +++ b/tts_service.py @@ -0,0 +1,68 @@ +import functools +import time +import logging +logging.basicConfig(level = logging.INFO) + +from websockets.sync.server import serve +from whisperspeech.pipeline import Pipeline + +class WhisperSpeechTTS: + def __init__(self): + pass + + def initialize_model(self): + self.pipe = Pipeline(s2a_ref='collabora/whisperspeech:s2a-q4-tiny-en+pl.model', torch_compile=True) + self.last_llm_response = None + + def run(self, host, port, audio_queue=None): + # initialize and warmup model + self.initialize_model() + for i in range(3): self.pipe.generate("Hello, I am warming up.") + + with serve( + functools.partial(self.start_whisperspeech_tts, audio_queue=audio_queue), + host, port + ) as server: + server.serve_forever() + + def start_whisperspeech_tts(self, websocket, audio_queue=None): + self.eos = False + self.output_audio = None + + while True: + llm_response = audio_queue.get() + if audio_queue.qsize() != 0: + continue + + # check if this websocket exists + try: + websocket.ping() + except Exception as e: + del websocket + audio_queue.put(llm_response) + break + + llm_output = llm_response["llm_output"][0] + self.eos = llm_response["eos"] + + def should_abort(): + if not audio_queue.empty(): raise TimeoutError() + + # only process if the output updated + if self.last_llm_response != llm_output.strip(): + try: + start = time.time() + audio = self.pipe.generate(llm_output.strip(), step_callback=should_abort) + inference_time = time.time() - start + logging.info(f"[WhisperSpeech INFO:] TTS inference done in {inference_time} ms.\n\n") + self.output_audio = audio.cpu().numpy() + self.last_llm_response = llm_output.strip() + except TimeoutError: + pass + + if self.eos and self.output_audio is not None: + try: + websocket.send(self.output_audio.tobytes()) + except Exception as e: + logging.error(f"[WhisperSpeech ERROR:] Audio error: {e}") + diff --git a/whisper_live/__init__.py b/whisper_live/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/whisper_live/client.py b/whisper_live/client.py new file mode 100644 index 0000000000000000000000000000000000000000..cee166897d7d227f745643ed4ac8dc2e95e5dd72 --- /dev/null +++ b/whisper_live/client.py @@ -0,0 +1,574 @@ +import os +import wave + +import numpy as np +import scipy +import ffmpeg +import pyaudio +import threading +import textwrap +import json +import websocket +import uuid +import time + + +def resample(file: str, sr: int = 16000): + """ + # https://github.com/openai/whisper/blob/7858aa9c08d98f75575035ecd6481f462d66ca27/whisper/audio.py#L22 + Open an audio file and read as mono waveform, resampling as necessary, + save the resampled audio + + Args: + file (str): The audio file to open + sr (int): The sample rate to resample the audio if necessary + + Returns: + resampled_file (str): The resampled audio file + """ + try: + # This launches a subprocess to decode audio while down-mixing and resampling as necessary. + # Requires the ffmpeg CLI and `ffmpeg-python` package to be installed. + out, _ = ( + ffmpeg.input(file, threads=0) + .output("-", format="s16le", acodec="pcm_s16le", ac=1, ar=sr) + .run(cmd=["ffmpeg", "-nostdin"], capture_stdout=True, capture_stderr=True) + ) + except ffmpeg.Error as e: + raise RuntimeError(f"Failed to load audio: {e.stderr.decode()}") from e + np_buffer = np.frombuffer(out, dtype=np.int16) + + resampled_file = f"{file.split('.')[0]}_resampled.wav" + scipy.io.wavfile.write(resampled_file, sr, np_buffer.astype(np.int16)) + return resampled_file + + +class Client: + """ + Handles audio recording, streaming, and communication with a server using WebSocket. + """ + INSTANCES = {} + + def __init__( + self, host=None, port=None, is_multilingual=False, lang=None, translate=False, model_size="small" + ): + """ + Initializes a Client instance for audio recording and streaming to a server. + + If host and port are not provided, the WebSocket connection will not be established. + When translate is True, the task will be set to "translate" instead of "transcribe". + he audio recording starts immediately upon initialization. + + Args: + host (str): The hostname or IP address of the server. + port (int): The port number for the WebSocket server. + is_multilingual (bool, optional): Specifies if multilingual transcription is enabled. Default is False. + lang (str, optional): The selected language for transcription when multilingual is disabled. Default is None. + translate (bool, optional): Specifies if the task is translation. Default is False. + """ + self.chunk = 1024 * 3 + self.format = pyaudio.paInt16 + self.channels = 1 + self.rate = 16000 + self.record_seconds = 60000 + self.recording = False + self.multilingual = False + self.language = None + self.task = "transcribe" + self.uid = str(uuid.uuid4()) + self.waiting = False + self.last_response_recieved = None + self.disconnect_if_no_response_for = 15 + self.multilingual = is_multilingual + self.language = lang + self.model_size = model_size + self.server_error = False + if translate: + self.task = "translate" + + self.timestamp_offset = 0.0 + self.audio_bytes = None + self.p = pyaudio.PyAudio() + self.stream = self.p.open( + format=self.format, + channels=self.channels, + rate=self.rate, + input=True, + frames_per_buffer=self.chunk, + ) + + if host is not None and port is not None: + socket_url = f"ws://{host}:{port}" + self.client_socket = websocket.WebSocketApp( + socket_url, + on_open=lambda ws: self.on_open(ws), + on_message=lambda ws, message: self.on_message(ws, message), + on_error=lambda ws, error: self.on_error(ws, error), + on_close=lambda ws, close_status_code, close_msg: self.on_close( + ws, close_status_code, close_msg + ), + ) + else: + print("[ERROR]: No host or port specified.") + return + + Client.INSTANCES[self.uid] = self + + # start websocket client in a thread + self.ws_thread = threading.Thread(target=self.client_socket.run_forever) + self.ws_thread.setDaemon(True) + self.ws_thread.start() + + self.frames = b"" + print("[INFO]: * recording") + + # TTS audio websocket client + socket_url = f"ws://{host}:8888" + self.tts_client_socket = websocket.WebSocketApp( + socket_url, + on_open=lambda ws: self.on_open_tts(ws), + on_message=lambda ws, message: self.on_message_tts(ws, message), + on_error=lambda ws, error: self.on_error_tts(ws, error), + on_close=lambda ws, close_status_code, close_msg: self.on_close_tts( + ws, close_status_code, close_msg + ), + ) + + self.tts_ws_thread = threading.Thread(target=self.tts_client_socket.run_forever) + self.tts_ws_thread.setDaemon(True) + self.tts_ws_thread.start() + + def on_message(self, ws, message): + """ + Callback function called when a message is received from the server. + + It updates various attributes of the client based on the received message, including + recording status, language detection, and server messages. If a disconnect message + is received, it sets the recording status to False. + + Args: + ws (websocket.WebSocketApp): The WebSocket client instance. + message (str): The received message from the server. + + """ + self.last_response_recieved = time.time() + message = json.loads(message) + + if self.uid != message.get("uid"): + print("[ERROR]: invalid client uid") + return + + if "status" in message.keys(): + if message["status"] == "WAIT": + self.waiting = True + print( + f"[INFO]:Server is full. Estimated wait time {round(message['message'])} minutes." + ) + elif message["status"] == "ERROR": + print(f"Message from Server: {message['message']}") + self.server_error = True + return + + if "message" in message.keys() and message["message"] == "DISCONNECT": + print("[INFO]: Server overtime disconnected.") + self.recording = False + + if "message" in message.keys() and message["message"] == "SERVER_READY": + self.recording = True + return + + if "language" in message.keys(): + self.language = message.get("language") + lang_prob = message.get("language_prob") + print( + f"[INFO]: Server detected language {self.language} with probability {lang_prob}" + ) + return + + if "llm_output" in message.keys(): + print("LLM output: ") + for item in message["llm_output"]: + print(item) + + + if "segments" not in message.keys(): + return + + message = message["segments"] + text = [] + print(message) + if len(message): + for seg in message: + if text and text[-1] == seg["text"]: + # already got it + continue + text.append(seg["text"]) + # keep only last 3 + if len(text) > 3: + text = text[-3:] + wrapper = textwrap.TextWrapper(width=60) + word_list = wrapper.wrap(text="".join(text)) + # Print each line. + # if os.name == "nt": + # os.system("cls") + # else: + # os.system("clear") + for element in word_list: + print(element) + + def on_error(self, ws, error): + print(error) + + def on_close(self, ws, close_status_code, close_msg): + print(f"[INFO]: Websocket connection closed: {close_status_code}: {close_msg}") + + def on_open(self, ws): + """ + Callback function called when the WebSocket connection is successfully opened. + + Sends an initial configuration message to the server, including client UID, multilingual mode, + language selection, and task type. + + Args: + ws (websocket.WebSocketApp): The WebSocket client instance. + + """ + print(self.multilingual, self.language, self.task) + + print("[INFO]: Opened connection") + ws.send( + json.dumps( + { + "uid": self.uid, + "multilingual": self.multilingual, + "language": self.language, + "task": self.task, + "model_size": self.model_size, + } + ) + ) + + def on_open_tts(self): + pass + + def on_message_tts(self, ws, message): + # print(message) + print(type(message)) + self.write_audio_frames_to_file(message.tobytes(), "tts_out.wav", rate=24000) + pass + + def on_error_tts(self, ws, error): + print(error) + + def on_close_tts(self, ws, close_status_code, close_msg): + print(f"[INFO]: Websocket connection closed: {close_status_code}: {close_msg}") + + @staticmethod + def bytes_to_float_array(audio_bytes): + """ + Convert audio data from bytes to a NumPy float array. + + It assumes that the audio data is in 16-bit PCM format. The audio data is normalized to + have values between -1 and 1. + + Args: + audio_bytes (bytes): Audio data in bytes. + + Returns: + np.ndarray: A NumPy array containing the audio data as float values normalized between -1 and 1. + """ + raw_data = np.frombuffer(buffer=audio_bytes, dtype=np.int16) + return raw_data.astype(np.float32) / 32768.0 + + def send_packet_to_server(self, message): + """ + Send an audio packet to the server using WebSocket. + + Args: + message (bytes): The audio data packet in bytes to be sent to the server. + + """ + try: + self.client_socket.send(message, websocket.ABNF.OPCODE_BINARY) + except Exception as e: + print(e) + + def play_file(self, filename): + """ + Play an audio file and send it to the server for processing. + + Reads an audio file, plays it through the audio output, and simultaneously sends + the audio data to the server for processing. It uses PyAudio to create an audio + stream for playback. The audio data is read from the file in chunks, converted to + floating-point format, and sent to the server using WebSocket communication. + This method is typically used when you want to process pre-recorded audio and send it + to the server in real-time. + + Args: + filename (str): The path to the audio file to be played and sent to the server. + """ + + # read audio and create pyaudio stream + with wave.open(filename, "rb") as wavfile: + self.stream = self.p.open( + format=self.p.get_format_from_width(wavfile.getsampwidth()), + channels=wavfile.getnchannels(), + rate=wavfile.getframerate(), + input=True, + output=True, + frames_per_buffer=self.chunk, + ) + try: + while self.recording: + data = wavfile.readframes(self.chunk) + if data == b"": + break + + audio_array = self.bytes_to_float_array(data) + self.send_packet_to_server(audio_array.tobytes()) + self.stream.write(data) + + wavfile.close() + + assert self.last_response_recieved + while time.time() - self.last_response_recieved < self.disconnect_if_no_response_for: + continue + self.stream.close() + self.close_websocket() + + except KeyboardInterrupt: + wavfile.close() + self.stream.stop_stream() + self.stream.close() + self.p.terminate() + self.close_websocket() + print("[INFO]: Keyboard interrupt.") + + def close_websocket(self): + """ + Close the WebSocket connection and join the WebSocket thread. + + First attempts to close the WebSocket connection using `self.client_socket.close()`. After + closing the connection, it joins the WebSocket thread to ensure proper termination. + + """ + try: + self.client_socket.close() + except Exception as e: + print("[ERROR]: Error closing WebSocket:", e) + + try: + self.ws_thread.join() + except Exception as e: + print("[ERROR:] Error joining WebSocket thread:", e) + + def get_client_socket(self): + """ + Get the WebSocket client socket instance. + + Returns: + WebSocketApp: The WebSocket client socket instance currently in use by the client. + """ + return self.client_socket + + def write_audio_frames_to_file(self, frames, file_name, rate=None): + """ + Write audio frames to a WAV file. + + The WAV file is created or overwritten with the specified name. The audio frames should be + in the correct format and match the specified channel, sample width, and sample rate. + + Args: + frames (bytes): The audio frames to be written to the file. + file_name (str): The name of the WAV file to which the frames will be written. + + """ + with wave.open(file_name, "wb") as wavfile: + wavfile: wave.Wave_write + wavfile.setnchannels(self.channels) + wavfile.setsampwidth(2) + wavfile.setframerate(self.rate if rate is None else rate) + wavfile.writeframes(frames) + + def process_hls_stream(self, hls_url): + """ + Connect to an HLS source, process the audio stream, and send it for transcription. + + Args: + hls_url (str): The URL of the HLS stream source. + """ + print("[INFO]: Connecting to HLS stream...") + process = None # Initialize process to None + + try: + # Connecting to the HLS stream using ffmpeg-python + process = ( + ffmpeg + .input(hls_url, threads=0) + .output('-', format='s16le', acodec='pcm_s16le', ac=1, ar=self.rate) + .run_async(pipe_stdout=True, pipe_stderr=True) + ) + + # Process the stream + while True: + in_bytes = process.stdout.read(self.chunk * 2) # 2 bytes per sample + if not in_bytes: + break + audio_array = self.bytes_to_float_array(in_bytes) + self.send_packet_to_server(audio_array.tobytes()) + + except Exception as e: + print(f"[ERROR]: Failed to connect to HLS stream: {e}") + finally: + if process: + process.kill() + + print("[INFO]: HLS stream processing finished.") + + + def record(self, out_file="output_recording.wav"): + """ + Record audio data from the input stream and save it to a WAV file. + + Continuously records audio data from the input stream, sends it to the server via a WebSocket + connection, and simultaneously saves it to multiple WAV files in chunks. It stops recording when + the `RECORD_SECONDS` duration is reached or when the `RECORDING` flag is set to `False`. + + Audio data is saved in chunks to the "chunks" directory. Each chunk is saved as a separate WAV file. + The recording will continue until the specified duration is reached or until the `RECORDING` flag is set to `False`. + The recording process can be interrupted by sending a KeyboardInterrupt (e.g., pressing Ctrl+C). After recording, + the method combines all the saved audio chunks into the specified `out_file`. + + Args: + out_file (str, optional): The name of the output WAV file to save the entire recording. Default is "output_recording.wav". + + """ + n_audio_file = 0 + if not os.path.exists("chunks"): + os.makedirs("chunks", exist_ok=True) + try: + for _ in range(0, int(self.rate / self.chunk * self.record_seconds)): + if not self.recording: + break + data = self.stream.read(self.chunk) + self.frames += data + + audio_array = Client.bytes_to_float_array(data) + + self.send_packet_to_server(audio_array.tobytes()) + + # save frames if more than a minute + if len(self.frames) > 60 * self.rate: + t = threading.Thread( + target=self.write_audio_frames_to_file, + args=( + self.frames[:], + f"chunks/{n_audio_file}.wav", + ), + ) + t.start() + n_audio_file += 1 + self.frames = b"" + + except KeyboardInterrupt: + if len(self.frames): + self.write_audio_frames_to_file( + self.frames[:], f"chunks/{n_audio_file}.wav" + ) + n_audio_file += 1 + self.stream.stop_stream() + self.stream.close() + self.p.terminate() + self.close_websocket() + + self.write_output_recording(n_audio_file, out_file) + + def write_output_recording(self, n_audio_file, out_file): + """ + Combine and save recorded audio chunks into a single WAV file. + + The individual audio chunk files are expected to be located in the "chunks" directory. Reads each chunk + file, appends its audio data to the final recording, and then deletes the chunk file. After combining + and saving, the final recording is stored in the specified `out_file`. + + + Args: + n_audio_file (int): The number of audio chunk files to combine. + out_file (str): The name of the output WAV file to save the final recording. + + """ + input_files = [ + f"chunks/{i}.wav" + for i in range(n_audio_file) + if os.path.exists(f"chunks/{i}.wav") + ] + with wave.open(out_file, "wb") as wavfile: + wavfile: wave.Wave_write + wavfile.setnchannels(self.channels) + wavfile.setsampwidth(2) + wavfile.setframerate(self.rate) + for in_file in input_files: + with wave.open(in_file, "rb") as wav_in: + while True: + data = wav_in.readframes(self.chunk) + if data == b"": + break + wavfile.writeframes(data) + # remove this file + os.remove(in_file) + wavfile.close() + + +class TranscriptionClient: + """ + Client for handling audio transcription tasks via a WebSocket connection. + + Acts as a high-level client for audio transcription tasks using a WebSocket connection. It can be used + to send audio data for transcription to a server and receive transcribed text segments. + + Args: + host (str): The hostname or IP address of the server. + port (int): The port number to connect to on the server. + is_multilingual (bool, optional): Indicates whether the transcription should support multiple languages (default is False). + lang (str, optional): The primary language for transcription (used if `is_multilingual` is False). Default is None, which defaults to English ('en'). + translate (bool, optional): Indicates whether translation tasks are required (default is False). + + Attributes: + client (Client): An instance of the underlying Client class responsible for handling the WebSocket connection. + + Example: + To create a TranscriptionClient and start transcription on microphone audio: + ```python + transcription_client = TranscriptionClient(host="localhost", port=9090, is_multilingual=True) + transcription_client() + ``` + """ + def __init__(self, host, port, is_multilingual=False, lang=None, translate=False, model_size="small"): + self.client = Client(host, port, is_multilingual, lang, translate, model_size) + + def __call__(self, audio=None, hls_url=None): + """ + Start the transcription process. + + Initiates the transcription process by connecting to the server via a WebSocket. It waits for the server + to be ready to receive audio data and then sends audio for transcription. If an audio file is provided, it + will be played and streamed to the server; otherwise, it will perform live recording. + + Args: + audio (str, optional): Path to an audio file for transcription. Default is None, which triggers live recording. + + """ + print("[INFO]: Waiting for server ready ...") + while not self.client.recording: + if self.client.waiting or self.client.server_error: + self.client.close_websocket() + return + + print("[INFO]: Server Ready!") + if hls_url is not None: + self.client.process_hls_stream(hls_url) + elif audio is not None: + resampled_file = resample(audio) + self.client.play_file(resampled_file) + else: + self.client.record() diff --git a/whisper_live/server.py b/whisper_live/server.py new file mode 100644 index 0000000000000000000000000000000000000000..0ec4346bf4acae6c81cea12a54d019db78e152b2 --- /dev/null +++ b/whisper_live/server.py @@ -0,0 +1,498 @@ +import websockets +import time +import threading +import json +import textwrap + +import logging +logging.basicConfig(level = logging.INFO) + +from websockets.sync.server import serve + +import torch +import numpy as np +import time +from whisper_live.transcriber import WhisperModel + + +class TranscriptionServer: + """ + Represents a transcription server that handles incoming audio from clients. + + Attributes: + RATE (int): The audio sampling rate (constant) set to 16000. + vad_model (torch.Module): The voice activity detection model. + vad_threshold (float): The voice activity detection threshold. + clients (dict): A dictionary to store connected clients. + websockets (dict): A dictionary to store WebSocket connections. + clients_start_time (dict): A dictionary to track client start times. + max_clients (int): Maximum allowed connected clients. + max_connection_time (int): Maximum allowed connection time in seconds. + """ + + RATE = 16000 + + def __init__(self): + # voice activity detection model + + self.clients = {} + self.websockets = {} + self.clients_start_time = {} + self.max_clients = 4 + self.max_connection_time = 600 + + def get_wait_time(self): + """ + Calculate and return the estimated wait time for clients. + + Returns: + float: The estimated wait time in minutes. + """ + wait_time = None + + for k, v in self.clients_start_time.items(): + current_client_time_remaining = self.max_connection_time - (time.time() - v) + + if wait_time is None or current_client_time_remaining < wait_time: + wait_time = current_client_time_remaining + + return wait_time / 60 + + def recv_audio(self, websocket): + """ + Receive audio chunks from a client in an infinite loop. + + Continuously receives audio frames from a connected client + over a WebSocket connection. It processes the audio frames using a + voice activity detection (VAD) model to determine if they contain speech + or not. If the audio frame contains speech, it is added to the client's + audio data for ASR. + If the maximum number of clients is reached, the method sends a + "WAIT" status to the client, indicating that they should wait + until a slot is available. + If a client's connection exceeds the maximum allowed time, it will + be disconnected, and the client's resources will be cleaned up. + + Args: + websocket (WebSocket): The WebSocket connection for the client. + + Raises: + Exception: If there is an error during the audio frame processing. + """ + logging.info("New client connected") + options = websocket.recv() + options = json.loads(options) + + if len(self.clients) >= self.max_clients: + logging.warning("Client Queue Full. Asking client to wait ...") + wait_time = self.get_wait_time() + response = { + "uid": options["uid"], + "status": "WAIT", + "message": wait_time, + } + websocket.send(json.dumps(response)) + websocket.close() + del websocket + return + + client = ServeClient( + websocket, + multilingual=options["multilingual"], + language=options["language"], + task=options["task"], + client_uid=options["uid"] + ) + + self.clients[websocket] = client + self.clients_start_time[websocket] = time.time() + + while True: + try: + frame_data = websocket.recv() + frame_np = np.frombuffer(frame_data, dtype=np.float32) + + self.clients[websocket].add_frames(frame_np) + + elapsed_time = time.time() - self.clients_start_time[websocket] + if elapsed_time >= self.max_connection_time: + self.clients[websocket].disconnect() + logging.warning(f"{self.clients[websocket]} Client disconnected due to overtime.") + self.clients[websocket].cleanup() + self.clients.pop(websocket) + self.clients_start_time.pop(websocket) + websocket.close() + del websocket + break + + except Exception as e: + logging.error(e) + self.clients[websocket].cleanup() + self.clients.pop(websocket) + self.clients_start_time.pop(websocket) + logging.info("Connection Closed.") + logging.info(self.clients) + del websocket + break + + def run(self, host, port=9090): + """ + Run the transcription server. + + Args: + host (str): The host address to bind the server. + port (int): The port number to bind the server. + """ + with serve(self.recv_audio, host, port) as server: + server.serve_forever() + + +class ServeClient: + """ + Attributes: + RATE (int): The audio sampling rate (constant) set to 16000. + SERVER_READY (str): A constant message indicating that the server is ready. + DISCONNECT (str): A constant message indicating that the client should disconnect. + client_uid (str): A unique identifier for the client. + data (bytes): Accumulated audio data. + frames (bytes): Accumulated audio frames. + language (str): The language for transcription. + task (str): The task type, e.g., "transcribe." + transcriber (WhisperModel): The Whisper model for speech-to-text. + timestamp_offset (float): The offset in audio timestamps. + frames_np (numpy.ndarray): NumPy array to store audio frames. + frames_offset (float): The offset in audio frames. + text (list): List of transcribed text segments. + current_out (str): The current incomplete transcription. + prev_out (str): The previous incomplete transcription. + t_start (float): Timestamp for the start of transcription. + exit (bool): A flag to exit the transcription thread. + same_output_threshold (int): Threshold for consecutive same output segments. + show_prev_out_thresh (int): Threshold for showing previous output segments. + add_pause_thresh (int): Threshold for adding a pause (blank) segment. + transcript (list): List of transcribed segments. + send_last_n_segments (int): Number of last segments to send to the client. + wrapper (textwrap.TextWrapper): Text wrapper for formatting text. + pick_previous_segments (int): Number of previous segments to include in the output. + websocket: The WebSocket connection for the client. + """ + RATE = 16000 + SERVER_READY = "SERVER_READY" + DISCONNECT = "DISCONNECT" + + def __init__(self, websocket, task="transcribe", device=None, multilingual=False, language=None, client_uid=None): + """ + Initialize a ServeClient instance. + The Whisper model is initialized based on the client's language and device availability. + The transcription thread is started upon initialization. A "SERVER_READY" message is sent + to the client to indicate that the server is ready. + + Args: + websocket (WebSocket): The WebSocket connection for the client. + task (str, optional): The task type, e.g., "transcribe." Defaults to "transcribe". + device (str, optional): The device type for Whisper, "cuda" or "cpu". Defaults to None. + multilingual (bool, optional): Whether the client supports multilingual transcription. Defaults to False. + language (str, optional): The language for transcription. Defaults to None. + client_uid (str, optional): A unique identifier for the client. Defaults to None. + + """ + self.client_uid = client_uid + self.data = b"" + self.frames = b"" + self.language = language if multilingual else "en" + self.task = task + device = "cuda" if torch.cuda.is_available() else "cpu" + self.transcriber = WhisperModel( + "small" if multilingual else "small.en", + device=device, + compute_type="int8" if device=="cpu" else "float16", + local_files_only=False, + ) + + self.timestamp_offset = 0.0 + self.frames_np = None + self.frames_offset = 0.0 + self.text = [] + self.current_out = '' + self.prev_out = '' + self.t_start=None + self.exit = False + self.same_output_threshold = 0 + self.show_prev_out_thresh = 5 # if pause(no output from whisper) show previous output for 5 seconds + self.add_pause_thresh = 3 # add a blank to segment list as a pause(no speech) for 3 seconds + self.transcript = [] + self.send_last_n_segments = 10 + + # text formatting + self.wrapper = textwrap.TextWrapper(width=50) + self.pick_previous_segments = 2 + + # threading + self.websocket = websocket + self.trans_thread = threading.Thread(target=self.speech_to_text) + self.trans_thread.start() + self.websocket.send( + json.dumps( + { + "uid": self.client_uid, + "message": self.SERVER_READY + } + ) + ) + + def fill_output(self, output): + """ + Format the current incomplete transcription output by combining it with previous complete segments. + The resulting transcription is wrapped into two lines, each containing a maximum of 50 characters. + + It ensures that the combined transcription fits within two lines, with a maximum of 50 characters per line. + Segments are concatenated in the order they exist in the list of previous segments, with the most + recent complete segment first and older segments prepended as needed to maintain the character limit. + If a 3-second pause is detected in the previous segments, any text preceding it is discarded to ensure + the transcription starts with the most recent complete content. The resulting transcription is returned + as a single string. + + Args: + output(str): The current incomplete transcription segment. + + Returns: + str: A formatted transcription wrapped in two lines. + """ + text = '' + pick_prev = min(len(self.text), self.pick_previous_segments) + for seg in self.text[-pick_prev:]: + # discard everything before a 3 second pause + if seg == '': + text = '' + else: + text += seg + wrapped = "".join(text + output) + return wrapped + + def add_frames(self, frame_np): + """ + Add audio frames to the ongoing audio stream buffer. + + This method is responsible for maintaining the audio stream buffer, allowing the continuous addition + of audio frames as they are received. It also ensures that the buffer does not exceed a specified size + to prevent excessive memory usage. + + If the buffer size exceeds a threshold (45 seconds of audio data), it discards the oldest 30 seconds + of audio data to maintain a reasonable buffer size. If the buffer is empty, it initializes it with the provided + audio frame. The audio stream buffer is used for real-time processing of audio data for transcription. + + Args: + frame_np (numpy.ndarray): The audio frame data as a NumPy array. + + """ + if self.frames_np is not None and self.frames_np.shape[0] > 45*self.RATE: + self.frames_offset += 30.0 + self.frames_np = self.frames_np[int(30*self.RATE):] + if self.frames_np is None: + self.frames_np = frame_np.copy() + else: + self.frames_np = np.concatenate((self.frames_np, frame_np), axis=0) + + def speech_to_text(self): + """ + Process an audio stream in an infinite loop, continuously transcribing the speech. + + This method continuously receives audio frames, performs real-time transcription, and sends + transcribed segments to the client via a WebSocket connection. + + If the client's language is not detected, it waits for 30 seconds of audio input to make a language prediction. + It utilizes the Whisper ASR model to transcribe the audio, continuously processing and streaming results. Segments + are sent to the client in real-time, and a history of segments is maintained to provide context.Pauses in speech + (no output from Whisper) are handled by showing the previous output for a set duration. A blank segment is added if + there is no speech for a specified duration to indicate a pause. + + Raises: + Exception: If there is an issue with audio processing or WebSocket communication. + + """ + while True: + if self.exit: + logging.info("Exiting speech to text thread") + break + + if self.frames_np is None: + continue + + # clip audio if the current chunk exceeds 30 seconds, this basically implies that + # no valid segment for the last 30 seconds from whisper + if self.frames_np[int((self.timestamp_offset - self.frames_offset)*self.RATE):].shape[0] > 25 * self.RATE: + duration = self.frames_np.shape[0] / self.RATE + self.timestamp_offset = self.frames_offset + duration - 5 + + samples_take = max(0, (self.timestamp_offset - self.frames_offset)*self.RATE) + input_bytes = self.frames_np[int(samples_take):].copy() + duration = input_bytes.shape[0] / self.RATE + if duration<1.0: + continue + try: + input_sample = input_bytes.copy() + + # whisper transcribe with prompt + result, info = self.transcriber.transcribe( + input_sample, + initial_prompt=None, + language=self.language, + task=self.task, + vad_filter=True, + vad_parameters={"threshold": 0.5} + ) + + if self.language is None: + if info.language_probability > 0.5: + self.language = info.language + logging.info(f"Detected language {self.language} with probability {info.language_probability}") + self.websocket.send(json.dumps( + {"uid": self.client_uid, "language": self.language, "language_prob": info.language_probability})) + else: + # detect language again + continue + + if len(result): + self.t_start = None + last_segment = self.update_segments(result, duration) + if len(self.transcript) < self.send_last_n_segments: + segments = self.transcript + else: + segments = self.transcript[-self.send_last_n_segments:] + if last_segment is not None: + segments = segments + [last_segment] + else: + # show previous output if there is pause i.e. no output from whisper + segments = [] + if self.t_start is None: self.t_start = time.time() + if time.time() - self.t_start < self.show_prev_out_thresh: + if len(self.transcript) < self.send_last_n_segments: + segments = self.transcript + else: + segments = self.transcript[-self.send_last_n_segments:] + + # add a blank if there is no speech for 3 seconds + if len(self.text) and self.text[-1] != '': + if time.time() - self.t_start > self.add_pause_thresh: + self.text.append('') + + try: + self.websocket.send( + json.dumps({ + "uid": self.client_uid, + "segments": segments + }) + ) + except Exception as e: + logging.error(f"[ERROR]: {e}") + + except Exception as e: + logging.error(f"[ERROR]: {e}") + time.sleep(0.01) + + def update_segments(self, segments, duration): + """ + Processes the segments from whisper. Appends all the segments to the list + except for the last segment assuming that it is incomplete. + + Updates the ongoing transcript with transcribed segments, including their start and end times. + Complete segments are appended to the transcript in chronological order. Incomplete segments + (assumed to be the last one) are processed to identify repeated content. If the same incomplete + segment is seen multiple times, it updates the offset and appends the segment to the transcript. + A threshold is used to detect repeated content and ensure it is only included once in the transcript. + The timestamp offset is updated based on the duration of processed segments. The method returns the + last processed segment, allowing it to be sent to the client for real-time updates. + + Args: + segments(dict) : dictionary of segments as returned by whisper + duration(float): duration of the current chunk + + Returns: + dict or None: The last processed segment with its start time, end time, and transcribed text. + Returns None if there are no valid segments to process. + """ + offset = None + self.current_out = '' + last_segment = None + # process complete segments + if len(segments) > 1: + for i, s in enumerate(segments[:-1]): + text_ = s.text + self.text.append(text_) + start, end = self.timestamp_offset + s.start, self.timestamp_offset + min(duration, s.end) + self.transcript.append( + { + 'start': start, + 'end': end, + 'text': text_ + } + ) + + offset = min(duration, s.end) + + self.current_out += segments[-1].text + last_segment = { + 'start': self.timestamp_offset + segments[-1].start, + 'end': self.timestamp_offset + min(duration, segments[-1].end), + 'text': self.current_out + } + + # if same incomplete segment is seen multiple times then update the offset + # and append the segment to the list + if self.current_out.strip() == self.prev_out.strip() and self.current_out != '': + self.same_output_threshold += 1 + else: + self.same_output_threshold = 0 + + if self.same_output_threshold > 5: + if not len(self.text) or self.text[-1].strip().lower()!=self.current_out.strip().lower(): + self.text.append(self.current_out) + self.transcript.append( + { + 'start': self.timestamp_offset, + 'end': self.timestamp_offset + duration, + 'text': self.current_out + } + ) + self.current_out = '' + offset = duration + self.same_output_threshold = 0 + last_segment = None + else: + self.prev_out = self.current_out + + # update offset + if offset is not None: + self.timestamp_offset += offset + + return last_segment + + def disconnect(self): + """ + Notify the client of disconnection and send a disconnect message. + + This method sends a disconnect message to the client via the WebSocket connection to notify them + that the transcription service is disconnecting gracefully. + + """ + self.websocket.send( + json.dumps( + { + "uid": self.client_uid, + "message": self.DISCONNECT + } + ) + ) + + def cleanup(self): + """ + Perform cleanup tasks before exiting the transcription service. + + This method performs necessary cleanup tasks, including stopping the transcription thread, marking + the exit flag to indicate the transcription thread should exit gracefully, and destroying resources + associated with the transcription process. + + """ + logging.info("Cleaning up.") + self.exit = True + self.transcriber.destroy() diff --git a/whisper_live/transcriber.py b/whisper_live/transcriber.py new file mode 100644 index 0000000000000000000000000000000000000000..a275878bc1b37672ead3476101eb8e5c47e599a6 --- /dev/null +++ b/whisper_live/transcriber.py @@ -0,0 +1,1023 @@ +# original https://github.com/guillaumekln/faster-whisper/blob/master/faster_whisper/transcribe.py + +import itertools +import logging +import os +import zlib + +from typing import BinaryIO, Iterable, List, NamedTuple, Optional, Tuple, Union + +import ctranslate2 +import numpy as np +import tokenizers + +from faster_whisper.audio import decode_audio +from faster_whisper.feature_extractor import FeatureExtractor +from faster_whisper.tokenizer import _LANGUAGE_CODES, Tokenizer +from faster_whisper.utils import download_model, format_timestamp, get_logger +from faster_whisper.vad import ( + SpeechTimestampsMap, + VadOptions, + collect_chunks, + get_speech_timestamps, +) + + +class Word(NamedTuple): + start: float + end: float + word: str + probability: float + + +class Segment(NamedTuple): + id: int + seek: int + start: float + end: float + text: str + tokens: List[int] + temperature: float + avg_logprob: float + compression_ratio: float + no_speech_prob: float + words: Optional[List[Word]] + + +class TranscriptionOptions(NamedTuple): + beam_size: int + best_of: int + patience: float + length_penalty: float + repetition_penalty: float + no_repeat_ngram_size: int + log_prob_threshold: Optional[float] + no_speech_threshold: Optional[float] + compression_ratio_threshold: Optional[float] + condition_on_previous_text: bool + prompt_reset_on_temperature: float + temperatures: List[float] + initial_prompt: Optional[Union[str, Iterable[int]]] + prefix: Optional[str] + suppress_blank: bool + suppress_tokens: Optional[List[int]] + without_timestamps: bool + max_initial_timestamp: float + word_timestamps: bool + prepend_punctuations: str + append_punctuations: str + + +class TranscriptionInfo(NamedTuple): + language: str + language_probability: float + duration: float + duration_after_vad: float + all_language_probs: Optional[List[Tuple[str, float]]] + transcription_options: TranscriptionOptions + vad_options: VadOptions + + +class WhisperModel: + def __init__( + self, + model_size_or_path: str, + device: str = "auto", + device_index: Union[int, List[int]] = 0, + compute_type: str = "default", + cpu_threads: int = 0, + num_workers: int = 1, + download_root: Optional[str] = None, + local_files_only: bool = False, + ): + """Initializes the Whisper model. + + Args: + model_size_or_path: Size of the model to use (tiny, tiny.en, base, base.en, + small, small.en, medium, medium.en, large-v1, large-v2, or large), a path to a converted + model directory, or a CTranslate2-converted Whisper model ID from the Hugging Face Hub. + When a size or a model ID is configured, the converted model is downloaded + from the Hugging Face Hub. + device: Device to use for computation ("cpu", "cuda", "auto"). + device_index: Device ID to use. + The model can also be loaded on multiple GPUs by passing a list of IDs + (e.g. [0, 1, 2, 3]). In that case, multiple transcriptions can run in parallel + when transcribe() is called from multiple Python threads (see also num_workers). + compute_type: Type to use for computation. + See https://opennmt.net/CTranslate2/quantization.html. + cpu_threads: Number of threads to use when running on CPU (4 by default). + A non zero value overrides the OMP_NUM_THREADS environment variable. + num_workers: When transcribe() is called from multiple Python threads, + having multiple workers enables true parallelism when running the model + (concurrent calls to self.model.generate() will run in parallel). + This can improve the global throughput at the cost of increased memory usage. + download_root: Directory where the models should be saved. If not set, the models + are saved in the standard Hugging Face cache directory. + local_files_only: If True, avoid downloading the file and return the path to the + local cached file if it exists. + """ + self.logger = get_logger() + + if os.path.isdir(model_size_or_path): + model_path = model_size_or_path + else: + model_path = download_model( + model_size_or_path, + local_files_only=local_files_only, + cache_dir=download_root, + ) + + self.model = ctranslate2.models.Whisper( + model_path, + device=device, + device_index=device_index, + compute_type=compute_type, + intra_threads=cpu_threads, + inter_threads=num_workers, + ) + + tokenizer_file = os.path.join(model_path, "tokenizer.json") + if os.path.isfile(tokenizer_file): + self.hf_tokenizer = tokenizers.Tokenizer.from_file(tokenizer_file) + else: + self.hf_tokenizer = tokenizers.Tokenizer.from_pretrained( + "openai/whisper-tiny" + ("" if self.model.is_multilingual else ".en") + ) + + self.feature_extractor = FeatureExtractor() + self.num_samples_per_token = self.feature_extractor.hop_length * 2 + self.frames_per_second = ( + self.feature_extractor.sampling_rate // self.feature_extractor.hop_length + ) + self.tokens_per_second = ( + self.feature_extractor.sampling_rate // self.num_samples_per_token + ) + self.input_stride = 2 + self.time_precision = 0.02 + self.max_length = 448 + + @property + def supported_languages(self) -> List[str]: + """The languages supported by the model.""" + return list(_LANGUAGE_CODES) if self.model.is_multilingual else ["en"] + + def transcribe( + self, + audio: Union[str, BinaryIO, np.ndarray], + language: Optional[str] = None, + task: str = "transcribe", + 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: Union[float, List[float], Tuple[float, ...]] = [ + 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[Union[str, Iterable[int]]] = None, + prefix: Optional[str] = None, + suppress_blank: bool = True, + suppress_tokens: Optional[List[int]] = [-1], + without_timestamps: bool = False, + max_initial_timestamp: float = 1.0, + word_timestamps: bool = False, + prepend_punctuations: str = "\"'“¿([{-", + append_punctuations: str = "\"'.。,,!!??::”)]}、", + vad_filter: bool = False, + vad_parameters: Optional[Union[dict, VadOptions]] = None, + ) -> Tuple[Iterable[Segment], TranscriptionInfo]: + """Transcribes an input file. + + Arguments: + audio: Path to the input file (or a file-like object), or the audio waveform. + language: The language spoken in the audio. It should be a language code such + as "en" or "fr". If not set, the language will be detected in the first 30 seconds + of audio. + task: Task to execute (transcribe or translate). + beam_size: Beam size to use for decoding. + best_of: Number of candidates when sampling with non-zero temperature. + patience: Beam search patience factor. + length_penalty: Exponential length penalty constant. + repetition_penalty: Penalty applied to the score of previously generated tokens + (set > 1 to penalize). + no_repeat_ngram_size: Prevent repetitions of ngrams with this size (set 0 to disable). + temperature: Temperature for sampling. It can be a tuple of temperatures, + which will be successively used upon failures according to either + `compression_ratio_threshold` or `log_prob_threshold`. + compression_ratio_threshold: If the gzip compression ratio is above this value, + treat as failed. + log_prob_threshold: If the average log probability over sampled tokens is + below this value, treat as failed. + no_speech_threshold: If the no_speech probability is higher than this value AND + the average log probability over sampled tokens is below `log_prob_threshold`, + consider the segment as silent. + condition_on_previous_text: If True, the previous output of the model is provided + as a prompt for the next window; disabling may make the text inconsistent across + windows, but the model becomes less prone to getting stuck in a failure loop, + such as repetition looping or timestamps going out of sync. + prompt_reset_on_temperature: Resets prompt if temperature is above this value. + Arg has effect only if condition_on_previous_text is True. + initial_prompt: Optional text string or iterable of token ids to provide as a + prompt for the first window. + prefix: Optional text to provide as a prefix for the first window. + suppress_blank: Suppress blank outputs at the beginning of the sampling. + suppress_tokens: List of token IDs to suppress. -1 will suppress a default set + of symbols as defined in the model config.json file. + without_timestamps: Only sample text tokens. + max_initial_timestamp: The initial timestamp cannot be later than this. + word_timestamps: Extract word-level timestamps using the cross-attention pattern + and dynamic time warping, and include the timestamps for each word in each segment. + prepend_punctuations: If word_timestamps is True, merge these punctuation symbols + with the next word + append_punctuations: If word_timestamps is True, merge these punctuation symbols + with the previous word + vad_filter: Enable the voice activity detection (VAD) to filter out parts of the audio + without speech. This step is using the Silero VAD model + https://github.com/snakers4/silero-vad. + vad_parameters: Dictionary of Silero VAD parameters or VadOptions class (see available + parameters and default values in the class `VadOptions`). + + Returns: + A tuple with: + + - a generator over transcribed segments + - an instance of TranscriptionInfo + """ + sampling_rate = self.feature_extractor.sampling_rate + + if not isinstance(audio, np.ndarray): + audio = decode_audio(audio, sampling_rate=sampling_rate) + + duration = audio.shape[0] / sampling_rate + duration_after_vad = duration + + self.logger.info( + "Processing audio with duration %s", format_timestamp(duration) + ) + + if vad_filter: + if vad_parameters is None: + vad_parameters = VadOptions() + elif isinstance(vad_parameters, dict): + vad_parameters = VadOptions(**vad_parameters) + speech_chunks = get_speech_timestamps(audio, vad_parameters) + audio = collect_chunks(audio, speech_chunks) + duration_after_vad = audio.shape[0] / sampling_rate + + self.logger.info( + "VAD filter removed %s of audio", + format_timestamp(duration - duration_after_vad), + ) + + if self.logger.isEnabledFor(logging.DEBUG): + self.logger.debug( + "VAD filter kept the following audio segments: %s", + ", ".join( + "[%s -> %s]" + % ( + format_timestamp(chunk["start"] / sampling_rate), + format_timestamp(chunk["end"] / sampling_rate), + ) + for chunk in speech_chunks + ), + ) + + else: + speech_chunks = None + + features = self.feature_extractor(audio) + + encoder_output = None + all_language_probs = None + + if language is None: + if not self.model.is_multilingual: + language = "en" + language_probability = 1 + else: + segment = features[:, : self.feature_extractor.nb_max_frames] + encoder_output = self.encode(segment) + # results is a list of tuple[str, float] with language names and + # probabilities. + results = self.model.detect_language(encoder_output)[0] + # Parse language names to strip out markers + all_language_probs = [(token[2:-2], prob) for (token, prob) in results] + # Get top language token and probability + language, language_probability = all_language_probs[0] + + self.logger.info( + "Detected language '%s' with probability %.2f", + language, + language_probability, + ) + else: + if not self.model.is_multilingual and language != "en": + self.logger.warning( + "The current model is English-only but the language parameter is set to '%s'; " + "using 'en' instead." % language + ) + language = "en" + + language_probability = 1 + + tokenizer = Tokenizer( + self.hf_tokenizer, + self.model.is_multilingual, + task=task, + language=language, + ) + + options = TranscriptionOptions( + beam_size=beam_size, + best_of=best_of, + patience=patience, + length_penalty=length_penalty, + repetition_penalty=repetition_penalty, + no_repeat_ngram_size=no_repeat_ngram_size, + log_prob_threshold=log_prob_threshold, + no_speech_threshold=no_speech_threshold, + compression_ratio_threshold=compression_ratio_threshold, + condition_on_previous_text=condition_on_previous_text, + prompt_reset_on_temperature=prompt_reset_on_temperature, + temperatures=( + temperature if isinstance(temperature, (list, tuple)) else [temperature] + ), + initial_prompt=initial_prompt, + prefix=prefix, + suppress_blank=suppress_blank, + suppress_tokens=get_suppressed_tokens(tokenizer, suppress_tokens), + without_timestamps=without_timestamps, + max_initial_timestamp=max_initial_timestamp, + word_timestamps=word_timestamps, + prepend_punctuations=prepend_punctuations, + append_punctuations=append_punctuations, + ) + + segments = self.generate_segments(features, tokenizer, options, encoder_output) + + if speech_chunks: + segments = restore_speech_timestamps(segments, speech_chunks, sampling_rate) + + info = TranscriptionInfo( + language=language, + language_probability=language_probability, + duration=duration, + duration_after_vad=duration_after_vad, + transcription_options=options, + vad_options=vad_parameters, + all_language_probs=all_language_probs, + ) + + return segments, info + + def generate_segments( + self, + features: np.ndarray, + tokenizer: Tokenizer, + options: TranscriptionOptions, + encoder_output: Optional[ctranslate2.StorageView] = None, + ) -> Iterable[Segment]: + content_frames = features.shape[-1] - self.feature_extractor.nb_max_frames + idx = 0 + seek = 0 + all_tokens = [] + prompt_reset_since = 0 + + if options.initial_prompt is not None: + if isinstance(options.initial_prompt, str): + initial_prompt = " " + options.initial_prompt.strip() + initial_prompt_tokens = tokenizer.encode(initial_prompt) + all_tokens.extend(initial_prompt_tokens) + else: + all_tokens.extend(options.initial_prompt) + + last_speech_timestamp = 0.0 + all_segments = [] + while seek < content_frames: + time_offset = seek * self.feature_extractor.time_per_frame + segment = features[:, seek : seek + self.feature_extractor.nb_max_frames] + segment_size = min( + self.feature_extractor.nb_max_frames, content_frames - seek + ) + segment_duration = segment_size * self.feature_extractor.time_per_frame + + if self.logger.isEnabledFor(logging.DEBUG): + self.logger.debug( + "Processing segment at %s", format_timestamp(time_offset) + ) + + previous_tokens = all_tokens[prompt_reset_since:] + prompt = self.get_prompt( + tokenizer, + previous_tokens, + without_timestamps=options.without_timestamps, + prefix=options.prefix if seek == 0 else None, + ) + + if seek > 0 or encoder_output is None: + encoder_output = self.encode(segment) + + ( + result, + avg_logprob, + temperature, + compression_ratio, + ) = self.generate_with_fallback(encoder_output, prompt, tokenizer, options) + + if options.no_speech_threshold is not None: + # no voice activity check + should_skip = result.no_speech_prob > options.no_speech_threshold + + if ( + options.log_prob_threshold is not None + and avg_logprob > options.log_prob_threshold + ): + # don't skip if the logprob is high enough, despite the no_speech_prob + should_skip = False + + if should_skip: + self.logger.debug( + "No speech threshold is met (%f > %f)", + result.no_speech_prob, + options.no_speech_threshold, + ) + + # fast-forward to the next segment boundary + seek += segment_size + continue + + tokens = result.sequences_ids[0] + + previous_seek = seek + current_segments = [] + + single_timestamp_ending = ( + len(tokens) >= 2 + and tokens[-2] < tokenizer.timestamp_begin + and tokens[-1] >= tokenizer.timestamp_begin + ) + + consecutive_timestamps = [ + i + for i in range(len(tokens)) + if i > 0 + and tokens[i] >= tokenizer.timestamp_begin + and tokens[i - 1] >= tokenizer.timestamp_begin + ] + + if len(consecutive_timestamps) > 0: + slices = list(consecutive_timestamps) + if single_timestamp_ending: + slices.append(len(tokens)) + + last_slice = 0 + for current_slice in slices: + sliced_tokens = tokens[last_slice:current_slice] + start_timestamp_position = ( + sliced_tokens[0] - tokenizer.timestamp_begin + ) + end_timestamp_position = ( + sliced_tokens[-1] - tokenizer.timestamp_begin + ) + start_time = ( + time_offset + start_timestamp_position * self.time_precision + ) + end_time = ( + time_offset + end_timestamp_position * self.time_precision + ) + + current_segments.append( + dict( + seek=seek, + start=start_time, + end=end_time, + tokens=sliced_tokens, + ) + ) + last_slice = current_slice + + if single_timestamp_ending: + # single timestamp at the end means no speech after the last timestamp. + seek += segment_size + else: + # otherwise, ignore the unfinished segment and seek to the last timestamp + last_timestamp_position = ( + tokens[last_slice - 1] - tokenizer.timestamp_begin + ) + seek += last_timestamp_position * self.input_stride + + else: + duration = segment_duration + timestamps = [ + token for token in tokens if token >= tokenizer.timestamp_begin + ] + if len(timestamps) > 0 and timestamps[-1] != tokenizer.timestamp_begin: + last_timestamp_position = timestamps[-1] - tokenizer.timestamp_begin + duration = last_timestamp_position * self.time_precision + + current_segments.append( + dict( + seek=seek, + start=time_offset, + end=time_offset + duration, + tokens=tokens, + ) + ) + + seek += segment_size + + if options.word_timestamps: + self.add_word_timestamps( + current_segments, + tokenizer, + encoder_output, + segment_size, + options.prepend_punctuations, + options.append_punctuations, + last_speech_timestamp=last_speech_timestamp, + ) + + word_end_timestamps = [ + w["end"] for s in current_segments for w in s["words"] + ] + if len(word_end_timestamps) > 0: + last_speech_timestamp = word_end_timestamps[-1] + if not single_timestamp_ending and len(word_end_timestamps) > 0: + seek_shift = round( + (word_end_timestamps[-1] - time_offset) * self.frames_per_second + ) + + if seek_shift > 0: + seek = previous_seek + seek_shift + + for segment in current_segments: + tokens = segment["tokens"] + text = tokenizer.decode(tokens) + + if segment["start"] == segment["end"] or not text.strip(): + continue + + all_tokens.extend(tokens) + idx += 1 + + all_segments.append(Segment( + id=idx, + seek=seek, + start=segment["start"], + end=segment["end"], + text=text, + tokens=tokens, + temperature=temperature, + avg_logprob=avg_logprob, + compression_ratio=compression_ratio, + no_speech_prob=result.no_speech_prob, + words=( + [Word(**word) for word in segment["words"]] + if options.word_timestamps + else None + ), + )) + + if ( + not options.condition_on_previous_text + or temperature > options.prompt_reset_on_temperature + ): + if options.condition_on_previous_text: + self.logger.debug( + "Reset prompt. prompt_reset_on_temperature threshold is met %f > %f", + temperature, + options.prompt_reset_on_temperature, + ) + + prompt_reset_since = len(all_tokens) + return all_segments + + def encode(self, features: np.ndarray) -> ctranslate2.StorageView: + # When the model is running on multiple GPUs, the encoder output should be moved + # to the CPU since we don't know which GPU will handle the next job. + to_cpu = self.model.device == "cuda" and len(self.model.device_index) > 1 + + features = np.expand_dims(features, 0) + features = get_ctranslate2_storage(features) + + return self.model.encode(features, to_cpu=to_cpu) + + def generate_with_fallback( + self, + encoder_output: ctranslate2.StorageView, + prompt: List[int], + tokenizer: Tokenizer, + options: TranscriptionOptions, + ) -> Tuple[ctranslate2.models.WhisperGenerationResult, float, float, float]: + decode_result = None + all_results = [] + below_cr_threshold_results = [] + + max_initial_timestamp_index = int( + round(options.max_initial_timestamp / self.time_precision) + ) + + for temperature in options.temperatures: + if temperature > 0: + kwargs = { + "beam_size": 1, + "num_hypotheses": options.best_of, + "sampling_topk": 0, + "sampling_temperature": temperature, + } + else: + kwargs = { + "beam_size": options.beam_size, + "patience": options.patience, + } + + result = self.model.generate( + encoder_output, + [prompt], + length_penalty=options.length_penalty, + repetition_penalty=options.repetition_penalty, + no_repeat_ngram_size=options.no_repeat_ngram_size, + max_length=self.max_length, + return_scores=True, + return_no_speech_prob=True, + suppress_blank=options.suppress_blank, + suppress_tokens=options.suppress_tokens, + max_initial_timestamp_index=max_initial_timestamp_index, + **kwargs, + )[0] + + tokens = result.sequences_ids[0] + + # Recover the average log prob from the returned score. + seq_len = len(tokens) + cum_logprob = result.scores[0] * (seq_len**options.length_penalty) + avg_logprob = cum_logprob / (seq_len + 1) + + text = tokenizer.decode(tokens).strip() + compression_ratio = get_compression_ratio(text) + + decode_result = ( + result, + avg_logprob, + temperature, + compression_ratio, + ) + all_results.append(decode_result) + + needs_fallback = False + + if options.compression_ratio_threshold is not None: + if compression_ratio > options.compression_ratio_threshold: + needs_fallback = True # too repetitive + + self.logger.debug( + "Compression ratio threshold is not met with temperature %.1f (%f > %f)", + temperature, + compression_ratio, + options.compression_ratio_threshold, + ) + else: + below_cr_threshold_results.append(decode_result) + + if ( + options.log_prob_threshold is not None + and avg_logprob < options.log_prob_threshold + ): + needs_fallback = True # average log probability is too low + + self.logger.debug( + "Log probability threshold is not met with temperature %.1f (%f < %f)", + temperature, + avg_logprob, + options.log_prob_threshold, + ) + + if ( + options.no_speech_threshold is not None + and result.no_speech_prob > options.no_speech_threshold + ): + needs_fallback = False # silence + + if not needs_fallback: + break + else: + # all failed, select the result with the highest average log probability + decode_result = max( + below_cr_threshold_results or all_results, key=lambda x: x[1] + ) + + return decode_result + + def get_prompt( + self, + tokenizer: Tokenizer, + previous_tokens: List[int], + without_timestamps: bool = False, + prefix: Optional[str] = None, + ) -> List[int]: + prompt = [] + + if previous_tokens: + prompt.append(tokenizer.sot_prev) + prompt.extend(previous_tokens[-(self.max_length // 2 - 1) :]) + + prompt.extend(tokenizer.sot_sequence) + + if without_timestamps: + prompt.append(tokenizer.no_timestamps) + + if prefix: + prefix_tokens = tokenizer.encode(" " + prefix.strip()) + if len(prefix_tokens) >= self.max_length // 2: + prefix_tokens = prefix_tokens[: self.max_length // 2 - 1] + if not without_timestamps: + prompt.append(tokenizer.timestamp_begin) + prompt.extend(prefix_tokens) + + return prompt + + def add_word_timestamps( + self, + segments: List[dict], + tokenizer: Tokenizer, + encoder_output: ctranslate2.StorageView, + num_frames: int, + prepend_punctuations: str, + append_punctuations: str, + last_speech_timestamp: float, + ) -> None: + if len(segments) == 0: + return + + text_tokens_per_segment = [ + [token for token in segment["tokens"] if token < tokenizer.eot] + for segment in segments + ] + + text_tokens = list(itertools.chain.from_iterable(text_tokens_per_segment)) + alignment = self.find_alignment( + tokenizer, text_tokens, encoder_output, num_frames + ) + word_durations = np.array([word["end"] - word["start"] for word in alignment]) + word_durations = word_durations[word_durations.nonzero()] + median_duration = np.median(word_durations) if len(word_durations) > 0 else 0.0 + max_duration = median_duration * 2 + + # hack: truncate long words at sentence boundaries. + # a better segmentation algorithm based on VAD should be able to replace this. + if len(word_durations) > 0: + sentence_end_marks = ".。!!??" + # ensure words at sentence boundaries + # are not longer than twice the median word duration. + for i in range(1, len(alignment)): + if alignment[i]["end"] - alignment[i]["start"] > max_duration: + if alignment[i]["word"] in sentence_end_marks: + alignment[i]["end"] = alignment[i]["start"] + max_duration + elif alignment[i - 1]["word"] in sentence_end_marks: + alignment[i]["start"] = alignment[i]["end"] - max_duration + + merge_punctuations(alignment, prepend_punctuations, append_punctuations) + + time_offset = ( + segments[0]["seek"] + * self.feature_extractor.hop_length + / self.feature_extractor.sampling_rate + ) + + word_index = 0 + + for segment, text_tokens in zip(segments, text_tokens_per_segment): + saved_tokens = 0 + words = [] + + while word_index < len(alignment) and saved_tokens < len(text_tokens): + timing = alignment[word_index] + + if timing["word"]: + words.append( + dict( + word=timing["word"], + start=round(time_offset + timing["start"], 2), + end=round(time_offset + timing["end"], 2), + probability=timing["probability"], + ) + ) + + saved_tokens += len(timing["tokens"]) + word_index += 1 + + # hack: truncate long words at segment boundaries. + # a better segmentation algorithm based on VAD should be able to replace this. + if len(words) > 0: + # ensure the first and second word after a pause is not longer than + # twice the median word duration. + if words[0]["end"] - last_speech_timestamp > median_duration * 4 and ( + words[0]["end"] - words[0]["start"] > max_duration + or ( + len(words) > 1 + and words[1]["end"] - words[0]["start"] > max_duration * 2 + ) + ): + if ( + len(words) > 1 + and words[1]["end"] - words[1]["start"] > max_duration + ): + boundary = max( + words[1]["end"] / 2, words[1]["end"] - max_duration + ) + words[0]["end"] = words[1]["start"] = boundary + words[0]["start"] = max(0, words[0]["end"] - max_duration) + + # prefer the segment-level start timestamp if the first word is too long. + if ( + segment["start"] < words[0]["end"] + and segment["start"] - 0.5 > words[0]["start"] + ): + words[0]["start"] = max( + 0, min(words[0]["end"] - median_duration, segment["start"]) + ) + else: + segment["start"] = words[0]["start"] + + # prefer the segment-level end timestamp if the last word is too long. + if ( + segment["end"] > words[-1]["start"] + and segment["end"] + 0.5 < words[-1]["end"] + ): + words[-1]["end"] = max( + words[-1]["start"] + median_duration, segment["end"] + ) + else: + segment["end"] = words[-1]["end"] + + last_speech_timestamp = segment["end"] + + segment["words"] = words + + def find_alignment( + self, + tokenizer: Tokenizer, + text_tokens: List[int], + encoder_output: ctranslate2.StorageView, + num_frames: int, + median_filter_width: int = 7, + ) -> List[dict]: + if len(text_tokens) == 0: + return [] + + result = self.model.align( + encoder_output, + tokenizer.sot_sequence, + [text_tokens], + num_frames, + median_filter_width=median_filter_width, + )[0] + + text_token_probs = result.text_token_probs + + alignments = result.alignments + text_indices = np.array([pair[0] for pair in alignments]) + time_indices = np.array([pair[1] for pair in alignments]) + + words, word_tokens = tokenizer.split_to_word_tokens( + text_tokens + [tokenizer.eot] + ) + word_boundaries = np.pad(np.cumsum([len(t) for t in word_tokens[:-1]]), (1, 0)) + if len(word_boundaries) <= 1: + return [] + + jumps = np.pad(np.diff(text_indices), (1, 0), constant_values=1).astype(bool) + jump_times = time_indices[jumps] / self.tokens_per_second + start_times = jump_times[word_boundaries[:-1]] + end_times = jump_times[word_boundaries[1:]] + word_probabilities = [ + np.mean(text_token_probs[i:j]) + for i, j in zip(word_boundaries[:-1], word_boundaries[1:]) + ] + + return [ + dict( + word=word, tokens=tokens, start=start, end=end, probability=probability + ) + for word, tokens, start, end, probability in zip( + words, word_tokens, start_times, end_times, word_probabilities + ) + ] + + def destroy(self): + del self.model + + +def restore_speech_timestamps( + segments: Iterable[Segment], + speech_chunks: List[dict], + sampling_rate: int, +) -> Iterable[Segment]: + ts_map = SpeechTimestampsMap(speech_chunks, sampling_rate) + + for segment in segments: + if segment.words: + words = [] + for word in segment.words: + # Ensure the word start and end times are resolved to the same chunk. + middle = (word.start + word.end) / 2 + chunk_index = ts_map.get_chunk_index(middle) + word = word._replace( + start=ts_map.get_original_time(word.start, chunk_index), + end=ts_map.get_original_time(word.end, chunk_index), + ) + words.append(word) + + segment = segment._replace( + start=words[0].start, + end=words[-1].end, + words=words, + ) + + else: + segment = segment._replace( + start=ts_map.get_original_time(segment.start), + end=ts_map.get_original_time(segment.end), + ) + + return segments + + +def get_ctranslate2_storage(segment: np.ndarray) -> ctranslate2.StorageView: + segment = np.ascontiguousarray(segment) + segment = ctranslate2.StorageView.from_array(segment) + return segment + + +def get_compression_ratio(text: str) -> float: + text_bytes = text.encode("utf-8") + return len(text_bytes) / len(zlib.compress(text_bytes)) + + +def get_suppressed_tokens( + tokenizer: Tokenizer, + suppress_tokens: Optional[List[int]], +) -> Optional[List[int]]: + if not suppress_tokens or -1 in suppress_tokens: + return suppress_tokens + + suppress_tokens = list(suppress_tokens) + + # Ensure the following special tokens are suppressed when the user does + # not use the default set (-1). + suppress_tokens.extend( + [ + tokenizer.transcribe, + tokenizer.translate, + tokenizer.sot, + tokenizer.sot_prev, + tokenizer.sot_lm, + ] + ) + + return sorted(set(suppress_tokens)) + + +def merge_punctuations(alignment: List[dict], prepended: str, appended: str) -> None: + # merge prepended punctuations + i = len(alignment) - 2 + j = len(alignment) - 1 + while i >= 0: + previous = alignment[i] + following = alignment[j] + if previous["word"].startswith(" ") and previous["word"].strip() in prepended: + # prepend it to the following word + following["word"] = previous["word"] + following["word"] + following["tokens"] = previous["tokens"] + following["tokens"] + previous["word"] = "" + previous["tokens"] = [] + else: + j = i + i -= 1 + + # merge appended punctuations + i = 0 + j = 1 + while j < len(alignment): + previous = alignment[i] + following = alignment[j] + if not previous["word"].endswith(" ") and following["word"] in appended: + # append it to the previous word + previous["word"] = previous["word"] + following["word"] + previous["tokens"] = previous["tokens"] + following["tokens"] + following["word"] = "" + following["tokens"] = [] + else: + i = j + j += 1 diff --git a/whisper_live/trt_server.py b/whisper_live/trt_server.py new file mode 100644 index 0000000000000000000000000000000000000000..4cc22d7283191fb9b0dbe8019e7e303e67713acc --- /dev/null +++ b/whisper_live/trt_server.py @@ -0,0 +1,435 @@ +import websockets +import time +import threading +import json +import textwrap + +import logging +logging.basicConfig(level = logging.INFO) + +from websockets.sync.server import serve + +import torch +import numpy as np +import queue + +from whisper_live.vad import VoiceActivityDetection +from whisper_live.trt_transcriber import WhisperTRTLLM + + +from scipy.io.wavfile import write +import functools + +save_counter = 0 +def save_wav(normalized_float32): + global save_counter + scaled_int16 = (normalized_float32 * 32768).astype(np.int16) + write(f"outputs/output{save_counter}.wav", 16000, scaled_int16) + save_counter += 1 + + + +class TranscriptionServer: + """ + Represents a transcription server that handles incoming audio from clients. + + Attributes: + RATE (int): The audio sampling rate (constant) set to 16000. + vad_model (torch.Module): The voice activity detection model. + vad_threshold (float): The voice activity detection threshold. + clients (dict): A dictionary to store connected clients. + websockets (dict): A dictionary to store WebSocket connections. + clients_start_time (dict): A dictionary to track client start times. + max_clients (int): Maximum allowed connected clients. + max_connection_time (int): Maximum allowed connection time in seconds. + """ + + RATE = 16000 + + def __init__(self): + # voice activity detection model + + self.clients = {} + self.websockets = {} + self.clients_start_time = {} + self.max_clients = 4 + self.max_connection_time = 600 + self.transcriber = None + + def get_wait_time(self): + """ + Calculate and return the estimated wait time for clients. + + Returns: + float: The estimated wait time in minutes. + """ + wait_time = None + + for k, v in self.clients_start_time.items(): + current_client_time_remaining = self.max_connection_time - (time.time() - v) + + if wait_time is None or current_client_time_remaining < wait_time: + wait_time = current_client_time_remaining + + return wait_time / 60 + + def recv_audio(self, websocket, transcription_queue=None, llm_queue=None, whisper_tensorrt_path=None): + """ + Receive audio chunks from a client in an infinite loop. + + Continuously receives audio frames from a connected client + over a WebSocket connection. It processes the audio frames using a + voice activity detection (VAD) model to determine if they contain speech + or not. If the audio frame contains speech, it is added to the client's + audio data for ASR. + If the maximum number of clients is reached, the method sends a + "WAIT" status to the client, indicating that they should wait + until a slot is available. + If a client's connection exceeds the maximum allowed time, it will + be disconnected, and the client's resources will be cleaned up. + + Args: + websocket (WebSocket): The WebSocket connection for the client. + + Raises: + Exception: If there is an error during the audio frame processing. + """ + self.vad_model = VoiceActivityDetection() + self.vad_threshold = 0.5 + + logging.info("[Whisper INFO:] New client connected") + options = websocket.recv() + options = json.loads(options) + + if len(self.clients) >= self.max_clients: + logging.warning("Client Queue Full. Asking client to wait ...") + wait_time = self.get_wait_time() + response = { + "uid": options["uid"], + "status": "WAIT", + "message": wait_time, + } + websocket.send(json.dumps(response)) + websocket.close() + del websocket + return + + if self.transcriber is None: + self.transcriber = WhisperTRTLLM(whisper_tensorrt_path, assets_dir="assets", device="cuda") + + client = ServeClient( + websocket, + multilingual=options["multilingual"], + language=options["language"], + task=options["task"], + client_uid=options["uid"], + transcription_queue=transcription_queue, + llm_queue=llm_queue, + transcriber=self.transcriber + ) + + self.clients[websocket] = client + self.clients_start_time[websocket] = time.time() + no_voice_activity_chunks = 0 + print() + while True: + try: + frame_data = websocket.recv() + frame_np = np.frombuffer(frame_data, dtype=np.float32) + + # VAD + try: + speech_prob = self.vad_model(torch.from_numpy(frame_np.copy()), self.RATE).item() + if speech_prob < self.vad_threshold: + no_voice_activity_chunks += 1 + if no_voice_activity_chunks > 3: + if not self.clients[websocket].eos: + self.clients[websocket].set_eos(True) + time.sleep(0.1) # EOS stop receiving frames for a 100ms(to send output to LLM.) + continue + no_voice_activity_chunks = 0 + self.clients[websocket].set_eos(False) + + except Exception as e: + logging.error(e) + return + self.clients[websocket].add_frames(frame_np) + + elapsed_time = time.time() - self.clients_start_time[websocket] + if elapsed_time >= self.max_connection_time: + self.clients[websocket].disconnect() + logging.warning(f"{self.clients[websocket]} Client disconnected due to overtime.") + self.clients[websocket].cleanup() + self.clients.pop(websocket) + self.clients_start_time.pop(websocket) + websocket.close() + del websocket + break + + except Exception as e: + logging.error(e) + self.clients[websocket].cleanup() + self.clients.pop(websocket) + self.clients_start_time.pop(websocket) + logging.info("[Whisper INFO:] Connection Closed.") + del websocket + break + + def run(self, host, port=9090, transcription_queue=None, llm_queue=None, whisper_tensorrt_path=None): + """ + Run the transcription server. + + Args: + host (str): The host address to bind the server. + port (int): The port number to bind the server. + """ + with serve( + functools.partial( + self.recv_audio, + transcription_queue=transcription_queue, + llm_queue=llm_queue, + whisper_tensorrt_path=whisper_tensorrt_path + ), + host, + port + ) as server: + server.serve_forever() + + +class ServeClient: + """ + Attributes: + RATE (int): The audio sampling rate (constant) set to 16000. + SERVER_READY (str): A constant message indicating that the server is ready. + DISCONNECT (str): A constant message indicating that the client should disconnect. + client_uid (str): A unique identifier for the client. + data (bytes): Accumulated audio data. + frames (bytes): Accumulated audio frames. + language (str): The language for transcription. + task (str): The task type, e.g., "transcribe." + transcriber (WhisperModel): The Whisper model for speech-to-text. + timestamp_offset (float): The offset in audio timestamps. + frames_np (numpy.ndarray): NumPy array to store audio frames. + frames_offset (float): The offset in audio frames. + exit (bool): A flag to exit the transcription thread. + transcript (list): List of transcribed segments. + websocket: The WebSocket connection for the client. + """ + RATE = 16000 + SERVER_READY = "SERVER_READY" + DISCONNECT = "DISCONNECT" + + def __init__( + self, + websocket, + task="transcribe", + device=None, + multilingual=False, + language=None, + client_uid=None, + transcription_queue=None, + llm_queue=None, + transcriber=None + ): + """ + Initialize a ServeClient instance. + The Whisper model is initialized based on the client's language and device availability. + The transcription thread is started upon initialization. A "SERVER_READY" message is sent + to the client to indicate that the server is ready. + + Args: + websocket (WebSocket): The WebSocket connection for the client. + task (str, optional): The task type, e.g., "transcribe." Defaults to "transcribe". + device (str, optional): The device type for Whisper, "cuda" or "cpu". Defaults to None. + multilingual (bool, optional): Whether the client supports multilingual transcription. Defaults to False. + language (str, optional): The language for transcription. Defaults to None. + client_uid (str, optional): A unique identifier for the client. Defaults to None. + + """ + if transcriber is None: + raise ValueError("Transcriber is None.") + self.transcriber = transcriber + self.client_uid = client_uid + self.transcription_queue = transcription_queue + self.llm_queue = llm_queue + self.data = b"" + self.frames = b"" + self.task = task + self.last_prompt = None + + self.timestamp_offset = 0.0 + self.frames_np = None + self.frames_offset = 0.0 + self.exit = False + self.transcript = [] + self.prompt = None + self.segment_inference_time = [] + + # threading + self.websocket = websocket + self.lock = threading.Lock() + self.eos = False + self.trans_thread = threading.Thread(target=self.speech_to_text) + self.trans_thread.start() + + self.websocket.send( + json.dumps( + { + "uid": self.client_uid, + "message": self.SERVER_READY + } + ) + ) + + def set_eos(self, eos): + self.lock.acquire() + self.eos = eos + self.lock.release() + + def add_frames(self, frame_np): + """ + Add audio frames to the ongoing audio stream buffer. + + This method is responsible for maintaining the audio stream buffer, allowing the continuous addition + of audio frames as they are received. It also ensures that the buffer does not exceed a specified size + to prevent excessive memory usage. + + If the buffer size exceeds a threshold (45 seconds of audio data), it discards the oldest 30 seconds + of audio data to maintain a reasonable buffer size. If the buffer is empty, it initializes it with the provided + audio frame. The audio stream buffer is used for real-time processing of audio data for transcription. + + Args: + frame_np (numpy.ndarray): The audio frame data as a NumPy array. + + """ + self.lock.acquire() + if self.frames_np is not None and self.frames_np.shape[0] > 45*self.RATE: + self.frames_offset += 30.0 + self.frames_np = self.frames_np[int(30*self.RATE):] + if self.frames_np is None: + self.frames_np = frame_np.copy() + else: + self.frames_np = np.concatenate((self.frames_np, frame_np), axis=0) + self.lock.release() + + def speech_to_text(self): + """ + Process an audio stream in an infinite loop, continuously transcribing the speech. + + This method continuously receives audio frames, performs real-time transcription, and sends + transcribed segments to the client via a WebSocket connection. + + If the client's language is not detected, it waits for 30 seconds of audio input to make a language prediction. + It utilizes the Whisper ASR model to transcribe the audio, continuously processing and streaming results. Segments + are sent to the client in real-time, and a history of segments is maintained to provide context.Pauses in speech + (no output from Whisper) are handled by showing the previous output for a set duration. A blank segment is added if + there is no speech for a specified duration to indicate a pause. + + Raises: + Exception: If there is an issue with audio processing or WebSocket communication. + + """ + while True: + # send the LLM outputs + try: + llm_response = None + if self.llm_queue is not None: + while not self.llm_queue.empty(): + llm_response = self.llm_queue.get() + + if llm_response: + eos = llm_response["eos"] + if eos: + self.websocket.send(json.dumps(llm_response)) + except queue.Empty: + pass + + if self.exit: + logging.info("[Whisper INFO:] Exiting speech to text thread") + break + + if self.frames_np is None: + time.sleep(0.02) # wait for any audio to arrive + continue + + # clip audio if the current chunk exceeds 30 seconds, this basically implies that + # no valid segment for the last 30 seconds from whisper + if self.frames_np[int((self.timestamp_offset - self.frames_offset)*self.RATE):].shape[0] > 25 * self.RATE: + duration = self.frames_np.shape[0] / self.RATE + self.timestamp_offset = self.frames_offset + duration - 5 + + samples_take = max(0, (self.timestamp_offset - self.frames_offset)*self.RATE) + input_bytes = self.frames_np[int(samples_take):].copy() + duration = input_bytes.shape[0] / self.RATE + if duration<0.4: + time.sleep(0.01) # 5ms sleep to wait for some voice active audio to arrive + continue + + try: + input_sample = input_bytes.copy() + start = time.time() + mel, duration = self.transcriber.log_mel_spectrogram(input_sample) + last_segment = self.transcriber.transcribe(mel) + infer_time = time.time() - start + self.segment_inference_time.append(infer_time) + + segments = [] + if len(last_segment): + segments.append({"text": last_segment}) + try: + self.prompt = ' '.join(segment['text'] for segment in segments) + if self.last_prompt != self.prompt: + self.websocket.send( + json.dumps({ + "uid": self.client_uid, + "segments": segments, + "eos": self.eos, + "latency": infer_time + }) + ) + + self.transcription_queue.put({"uid": self.client_uid, "prompt": self.prompt, "eos": self.eos}) + if self.eos: + self.timestamp_offset += duration + logging.info(f"[Whisper INFO]: {self.prompt}, eos: {self.eos}") + logging.info( + f"[Whisper INFO]: Average inference time {sum(self.segment_inference_time) / len(self.segment_inference_time)}\n\n") + self.segment_inference_time = [] + + + + except Exception as e: + logging.error(f"[ERROR]: {e}") + + except Exception as e: + logging.error(f"[ERROR]: {e}") + + def disconnect(self): + """ + Notify the client of disconnection and send a disconnect message. + + This method sends a disconnect message to the client via the WebSocket connection to notify them + that the transcription service is disconnecting gracefully. + + """ + self.websocket.send( + json.dumps( + { + "uid": self.client_uid, + "message": self.DISCONNECT + } + ) + ) + + def cleanup(self): + """ + Perform cleanup tasks before exiting the transcription service. + + This method performs necessary cleanup tasks, including stopping the transcription thread, marking + the exit flag to indicate the transcription thread should exit gracefully, and destroying resources + associated with the transcription process. + + """ + logging.info("Cleaning up.") + self.exit = True + # self.transcriber.destroy() diff --git a/whisper_live/trt_transcriber.py b/whisper_live/trt_transcriber.py new file mode 100644 index 0000000000000000000000000000000000000000..bdad5e0a13c8cf3b2d301f29093173f765c261d2 --- /dev/null +++ b/whisper_live/trt_transcriber.py @@ -0,0 +1,347 @@ +import argparse +import json +import re +import time +from collections import OrderedDict +from pathlib import Path +from typing import Dict, Iterable, List, Optional, TextIO, Tuple, Union + +import torch +import numpy as np +from whisper.tokenizer import get_tokenizer +from whisper_live.whisper_utils import (mel_filters, store_transcripts, + write_error_stats, load_audio_wav_format, + pad_or_trim) + +import tensorrt_llm +import tensorrt_llm.logger as logger +from tensorrt_llm._utils import (str_dtype_to_torch, str_dtype_to_trt, + trt_dtype_to_torch) +from tensorrt_llm.runtime import ModelConfig, SamplingConfig +from tensorrt_llm.runtime.session import Session, TensorInfo + + +SAMPLE_RATE = 16000 +N_FFT = 400 +HOP_LENGTH = 160 +CHUNK_LENGTH = 30 +N_SAMPLES = CHUNK_LENGTH * SAMPLE_RATE # 480000 samples in a 30-second chunk + + +class WhisperEncoding: + + def __init__(self, engine_dir): + self.session = self.get_session(engine_dir) + + def get_session(self, engine_dir): + config_path = engine_dir / 'encoder_config.json' + with open(config_path, 'r') as f: + config = json.load(f) + + use_gpt_attention_plugin = config['plugin_config'][ + 'gpt_attention_plugin'] + dtype = config['builder_config']['precision'] + n_mels = config['builder_config']['n_mels'] + num_languages = config['builder_config']['num_languages'] + + self.dtype = dtype + self.n_mels = n_mels + self.num_languages = num_languages + + serialize_path = engine_dir / f'whisper_encoder_{self.dtype}_tp1_rank0.engine' + + with open(serialize_path, 'rb') as f: + session = Session.from_serialized_engine(f.read()) + + return session + + def get_audio_features(self, mel): + inputs = OrderedDict() + output_list = [] + + inputs.update({'x': mel}) + output_list.append( + TensorInfo('x', str_dtype_to_trt(self.dtype), mel.shape)) + + output_info = (self.session).infer_shapes(output_list) + + logger.debug(f'output info {output_info}') + outputs = { + t.name: torch.empty(tuple(t.shape), + dtype=trt_dtype_to_torch(t.dtype), + device='cuda') + for t in output_info + } + stream = torch.cuda.current_stream() + ok = self.session.run(inputs=inputs, + outputs=outputs, + stream=stream.cuda_stream) + assert ok, 'Engine execution failed' + stream.synchronize() + audio_features = outputs['output'] + return audio_features + + +class WhisperDecoding: + + def __init__(self, engine_dir, runtime_mapping, debug_mode=False): + + self.decoder_config = self.get_config(engine_dir) + self.decoder_generation_session = self.get_session( + engine_dir, runtime_mapping, debug_mode) + + def get_config(self, engine_dir): + config_path = engine_dir / 'decoder_config.json' + with open(config_path, 'r') as f: + config = json.load(f) + decoder_config = OrderedDict() + decoder_config.update(config['plugin_config']) + decoder_config.update(config['builder_config']) + return decoder_config + + def get_session(self, engine_dir, runtime_mapping, debug_mode=False): + dtype = self.decoder_config['precision'] + serialize_path = engine_dir / f'whisper_decoder_{dtype}_tp1_rank0.engine' + with open(serialize_path, "rb") as f: + decoder_engine_buffer = f.read() + + decoder_model_config = ModelConfig( + num_heads=self.decoder_config['num_heads'], + num_kv_heads=self.decoder_config['num_heads'], + hidden_size=self.decoder_config['hidden_size'], + vocab_size=self.decoder_config['vocab_size'], + num_layers=self.decoder_config['num_layers'], + gpt_attention_plugin=self.decoder_config['gpt_attention_plugin'], + remove_input_padding=self.decoder_config['remove_input_padding'], + cross_attention=self.decoder_config['cross_attention'], + has_position_embedding=self. + decoder_config['has_position_embedding'], + has_token_type_embedding=self. + decoder_config['has_token_type_embedding'], + ) + decoder_generation_session = tensorrt_llm.runtime.GenerationSession( + decoder_model_config, + decoder_engine_buffer, + runtime_mapping, + debug_mode=debug_mode) + + return decoder_generation_session + + def generate(self, + decoder_input_ids, + encoder_outputs, + eot_id, + max_new_tokens=40, + num_beams=1): + encoder_input_lengths = torch.tensor( + [encoder_outputs.shape[1] for x in range(encoder_outputs.shape[0])], + dtype=torch.int32, + device='cuda') + + decoder_input_lengths = torch.tensor([ + decoder_input_ids.shape[-1] + for _ in range(decoder_input_ids.shape[0]) + ], + dtype=torch.int32, + device='cuda') + decoder_max_input_length = torch.max(decoder_input_lengths).item() + + # generation config + sampling_config = SamplingConfig(end_id=eot_id, + pad_id=eot_id, + num_beams=num_beams) + self.decoder_generation_session.setup( + decoder_input_lengths.size(0), + decoder_max_input_length, + max_new_tokens, + beam_width=num_beams, + encoder_max_input_length=encoder_outputs.shape[1]) + + torch.cuda.synchronize() + + decoder_input_ids = decoder_input_ids.type(torch.int32).cuda() + output_ids = self.decoder_generation_session.decode( + decoder_input_ids, + decoder_input_lengths, + sampling_config, + encoder_output=encoder_outputs, + encoder_input_lengths=encoder_input_lengths, + ) + torch.cuda.synchronize() + + # get the list of int from output_ids tensor + output_ids = output_ids.cpu().numpy().tolist() + return output_ids + + +class WhisperTRTLLM(object): + + def __init__( + self, + engine_dir, + debug_mode=False, + assets_dir=None, + device=None + ): + world_size = 1 + runtime_rank = tensorrt_llm.mpi_rank() + runtime_mapping = tensorrt_llm.Mapping(world_size, runtime_rank) + torch.cuda.set_device(runtime_rank % runtime_mapping.gpus_per_node) + engine_dir = Path(engine_dir) + + self.encoder = WhisperEncoding(engine_dir) + self.decoder = WhisperDecoding(engine_dir, + runtime_mapping, + debug_mode=False) + self.n_mels = self.encoder.n_mels + # self.tokenizer = get_tokenizer(num_languages=self.encoder.num_languages, + # tokenizer_dir=assets_dir) + self.device = device + self.tokenizer = get_tokenizer( + False, + # num_languages=self.encoder.num_languages, + language="en", + task="transcribe", + ) + self.filters = mel_filters(self.device, self.encoder.n_mels, assets_dir) + + def log_mel_spectrogram( + self, + audio: Union[str, np.ndarray, torch.Tensor], + padding: int = 0, + return_duration = True + ): + """ + Compute the log-Mel spectrogram of + + Parameters + ---------- + audio: Union[str, np.ndarray, torch.Tensor], shape = (*) + The path to audio or either a NumPy array or Tensor containing the audio waveform in 16 kHz + + n_mels: int + The number of Mel-frequency filters, only 80 and 128 are supported + + padding: int + Number of zero samples to pad to the right + + device: Optional[Union[str, torch.device]] + If given, the audio tensor is moved to this device before STFT + + Returns + ------- + torch.Tensor, shape = (80 or 128, n_frames) + A Tensor that contains the Mel spectrogram + """ + if not torch.is_tensor(audio): + if isinstance(audio, str): + if audio.endswith('.wav'): + audio, _ = load_audio_wav_format(audio) + else: + audio = load_audio(audio) + assert isinstance(audio, + np.ndarray), f"Unsupported audio type: {type(audio)}" + duration = audio.shape[-1] / SAMPLE_RATE + audio = pad_or_trim(audio, N_SAMPLES) + audio = audio.astype(np.float32) + audio = torch.from_numpy(audio) + + if self.device is not None: + audio = audio.to(self.device) + if padding > 0: + audio = F.pad(audio, (0, padding)) + window = torch.hann_window(N_FFT).to(audio.device) + stft = torch.stft(audio, + N_FFT, + HOP_LENGTH, + window=window, + return_complex=True) + magnitudes = stft[..., :-1].abs()**2 + + + mel_spec = self.filters @ magnitudes + + log_spec = torch.clamp(mel_spec, min=1e-10).log10() + log_spec = torch.maximum(log_spec, log_spec.max() - 8.0) + log_spec = (log_spec + 4.0) / 4.0 + if return_duration: + return log_spec, duration + else: + return log_spec + + + def process_batch( + self, + mel, + text_prefix="<|startoftranscript|><|en|><|transcribe|><|notimestamps|>", + num_beams=1): + prompt_id = self.tokenizer.encode( + text_prefix, allowed_special=set(self.tokenizer.special_tokens.keys())) + + prompt_id = torch.tensor(prompt_id) + batch_size = mel.shape[0] + decoder_input_ids = prompt_id.repeat(batch_size, 1) + + encoder_output = self.encoder.get_audio_features(mel) + output_ids = self.decoder.generate(decoder_input_ids, + encoder_output, + self.tokenizer.eot, + max_new_tokens=96, + num_beams=num_beams) + texts = [] + for i in range(len(output_ids)): + text = self.tokenizer.decode(output_ids[i][0]).strip() + texts.append(text) + return texts + + def transcribe( + self, + mel, + text_prefix="<|startoftranscript|><|en|><|transcribe|><|notimestamps|>", + dtype='float16', + batch_size=1, + num_beams=1, + ): + mel = mel.type(str_dtype_to_torch(dtype)) + mel = mel.unsqueeze(0) + predictions = self.process_batch(mel, text_prefix, num_beams) + prediction = predictions[0] + + # remove all special tokens in the prediction + prediction = re.sub(r'<\|.*?\|>', '', prediction) + return prediction.strip() + + +def decode_wav_file( + model, + mel, + text_prefix="<|startoftranscript|><|en|><|transcribe|><|notimestamps|>", + dtype='float16', + batch_size=1, + num_beams=1, + normalizer=None, + mel_filters_dir=None): + + mel = mel.type(str_dtype_to_torch(dtype)) + mel = mel.unsqueeze(0) + # repeat the mel spectrogram to match the batch size + mel = mel.repeat(batch_size, 1, 1) + predictions = model.process_batch(mel, text_prefix, num_beams) + prediction = predictions[0] + + # remove all special tokens in the prediction + prediction = re.sub(r'<\|.*?\|>', '', prediction) + if normalizer: + prediction = normalizer(prediction) + + return prediction.strip() + + +if __name__=="__main__": + tensorrt_llm.logger.set_level("error") + model = WhisperTRTLLM("/root/TensorRT-LLM/examples/whisper/whisper_small_en", False, "../assets", device="cuda") + mel, total_duration = model.log_mel_spectrogram( + "../assets/1221-135766-0002.wav", + ) + results = model.transcribe(mel) + print(results, total_duration) \ No newline at end of file diff --git a/whisper_live/vad.py b/whisper_live/vad.py new file mode 100644 index 0000000000000000000000000000000000000000..ec93333f88876744dd004d3679c906f4191814a4 --- /dev/null +++ b/whisper_live/vad.py @@ -0,0 +1,118 @@ +# original: https://github.com/snakers4/silero-vad/blob/master/utils_vad.py + +import os +import subprocess +import torch +import numpy as np +import onnxruntime + + +class VoiceActivityDetection(): + + def __init__(self, force_onnx_cpu=True): + print("downloading ONNX model...") + path = self.download() + print("loading session") + + opts = onnxruntime.SessionOptions() + opts.log_severity_level = 3 + + opts.inter_op_num_threads = 1 + opts.intra_op_num_threads = 1 + + print("loading onnx model") + if force_onnx_cpu and 'CPUExecutionProvider' in onnxruntime.get_available_providers(): + self.session = onnxruntime.InferenceSession(path, providers=['CPUExecutionProvider'], sess_options=opts) + else: + self.session = onnxruntime.InferenceSession(path, providers=['CUDAExecutionProvider'], sess_options=opts) + + print("reset states") + self.reset_states() + self.sample_rates = [8000, 16000] + + def _validate_input(self, x, sr: int): + if x.dim() == 1: + x = x.unsqueeze(0) + if x.dim() > 2: + raise ValueError(f"Too many dimensions for input audio chunk {x.dim()}") + + if sr != 16000 and (sr % 16000 == 0): + step = sr // 16000 + x = x[:,::step] + sr = 16000 + + if sr not in self.sample_rates: + raise ValueError(f"Supported sampling rates: {self.sample_rates} (or multiply of 16000)") + + if sr / x.shape[1] > 31.25: + raise ValueError("Input audio chunk is too short") + + return x, sr + + def reset_states(self, batch_size=1): + self._h = np.zeros((2, batch_size, 64)).astype('float32') + self._c = np.zeros((2, batch_size, 64)).astype('float32') + self._last_sr = 0 + self._last_batch_size = 0 + + def __call__(self, x, sr: int): + + x, sr = self._validate_input(x, sr) + batch_size = x.shape[0] + + if not self._last_batch_size: + self.reset_states(batch_size) + if (self._last_sr) and (self._last_sr != sr): + self.reset_states(batch_size) + if (self._last_batch_size) and (self._last_batch_size != batch_size): + self.reset_states(batch_size) + + if sr in [8000, 16000]: + ort_inputs = {'input': x.numpy(), 'h': self._h, 'c': self._c, 'sr': np.array(sr, dtype='int64')} + ort_outs = self.session.run(None, ort_inputs) + out, self._h, self._c = ort_outs + else: + raise ValueError() + + self._last_sr = sr + self._last_batch_size = batch_size + + out = torch.tensor(out) + return out + + def audio_forward(self, x, sr: int, num_samples: int = 512): + outs = [] + x, sr = self._validate_input(x, sr) + + if x.shape[1] % num_samples: + pad_num = num_samples - (x.shape[1] % num_samples) + x = torch.nn.functional.pad(x, (0, pad_num), 'constant', value=0.0) + + self.reset_states(x.shape[0]) + for i in range(0, x.shape[1], num_samples): + wavs_batch = x[:, i:i+num_samples] + out_chunk = self.__call__(wavs_batch, sr) + outs.append(out_chunk) + + stacked = torch.cat(outs, dim=1) + return stacked.cpu() + + @staticmethod + def download(model_url="https://github.com/snakers4/silero-vad/raw/master/files/silero_vad.onnx"): + target_dir = os.path.expanduser("~/.cache/whisper-live/") + + # Ensure the target directory exists + os.makedirs(target_dir, exist_ok=True) + + # Define the target file path + model_filename = os.path.join(target_dir, "silero_vad.onnx") + + # Check if the model file already exists + if not os.path.exists(model_filename): + # If it doesn't exist, download the model using wget + print("Downloading VAD ONNX model...") + try: + subprocess.run(["wget", "-O", model_filename, model_url], check=True) + except subprocess.CalledProcessError: + print("Failed to download the model using wget.") + return model_filename diff --git a/whisper_live/whisper_utils.py b/whisper_live/whisper_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..6c30d3576f888dfd4935fdc8d1f2ef97940b50cd --- /dev/null +++ b/whisper_live/whisper_utils.py @@ -0,0 +1,365 @@ +# SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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 logging +import os +from collections import defaultdict +from functools import lru_cache +from pathlib import Path +from subprocess import CalledProcessError, run +from typing import Dict, Iterable, List, Optional, TextIO, Tuple, Union + +import kaldialign +import numpy as np +import soundfile +import torch +import torch.nn.functional as F + +Pathlike = Union[str, Path] + +SAMPLE_RATE = 16000 +N_FFT = 400 +HOP_LENGTH = 160 +CHUNK_LENGTH = 30 +N_SAMPLES = CHUNK_LENGTH * SAMPLE_RATE # 480000 samples in a 30-second chunk + + +def load_audio(file: str, sr: int = SAMPLE_RATE): + """ + Open an audio file and read as mono waveform, resampling as necessary + + Parameters + ---------- + file: str + The audio file to open + + sr: int + The sample rate to resample the audio if necessary + + Returns + ------- + A NumPy array containing the audio waveform, in float32 dtype. + """ + + # This launches a subprocess to decode audio while down-mixing + # and resampling as necessary. Requires the ffmpeg CLI in PATH. + # fmt: off + cmd = [ + "ffmpeg", "-nostdin", "-threads", "0", "-i", file, "-f", "s16le", "-ac", + "1", "-acodec", "pcm_s16le", "-ar", + str(sr), "-" + ] + # fmt: on + try: + out = run(cmd, capture_output=True, check=True).stdout + except CalledProcessError as e: + raise RuntimeError(f"Failed to load audio: {e.stderr.decode()}") from e + + return np.frombuffer(out, np.int16).flatten().astype(np.float32) / 32768.0 + + +def load_audio_wav_format(wav_path): + # make sure audio in .wav format + assert wav_path.endswith( + '.wav'), f"Only support .wav format, but got {wav_path}" + waveform, sample_rate = soundfile.read(wav_path) + assert sample_rate == 16000, f"Only support 16k sample rate, but got {sample_rate}" + return waveform, sample_rate + + +def pad_or_trim(array, length: int = N_SAMPLES, *, axis: int = -1): + """ + Pad or trim the audio array to N_SAMPLES, as expected by the encoder. + """ + if torch.is_tensor(array): + if array.shape[axis] > length: + array = array.index_select(dim=axis, + index=torch.arange(length, + device=array.device)) + + if array.shape[axis] < length: + pad_widths = [(0, 0)] * array.ndim + pad_widths[axis] = (0, length - array.shape[axis]) + array = F.pad(array, + [pad for sizes in pad_widths[::-1] for pad in sizes]) + else: + if array.shape[axis] > length: + array = array.take(indices=range(length), axis=axis) + + if array.shape[axis] < length: + pad_widths = [(0, 0)] * array.ndim + pad_widths[axis] = (0, length - array.shape[axis]) + array = np.pad(array, pad_widths) + + return array + + +@lru_cache(maxsize=None) +def mel_filters(device, + n_mels: int, + mel_filters_dir: str = None) -> torch.Tensor: + """ + load the mel filterbank matrix for projecting STFT into a Mel spectrogram. + Allows decoupling librosa dependency; saved using: + + np.savez_compressed( + "mel_filters.npz", + mel_80=librosa.filters.mel(sr=16000, n_fft=400, n_mels=80), + ) + """ + assert n_mels in {80, 128}, f"Unsupported n_mels: {n_mels}" + if mel_filters_dir is None: + mel_filters_path = os.path.join(os.path.dirname(__file__), "assets", + "mel_filters.npz") + else: + mel_filters_path = os.path.join(mel_filters_dir, "mel_filters.npz") + with np.load(mel_filters_path) as f: + return torch.from_numpy(f[f"mel_{n_mels}"]).to(device) + + +def log_mel_spectrogram( + audio: Union[str, np.ndarray, torch.Tensor], + n_mels: int, + padding: int = 0, + device: Optional[Union[str, torch.device]] = None, + return_duration: bool = False, + mel_filters_dir: str = None, +): + """ + Compute the log-Mel spectrogram of + + Parameters + ---------- + audio: Union[str, np.ndarray, torch.Tensor], shape = (*) + The path to audio or either a NumPy array or Tensor containing the audio waveform in 16 kHz + + n_mels: int + The number of Mel-frequency filters, only 80 and 128 are supported + + padding: int + Number of zero samples to pad to the right + + device: Optional[Union[str, torch.device]] + If given, the audio tensor is moved to this device before STFT + + Returns + ------- + torch.Tensor, shape = (80 or 128, n_frames) + A Tensor that contains the Mel spectrogram + """ + if not torch.is_tensor(audio): + if isinstance(audio, str): + if audio.endswith('.wav'): + audio, _ = load_audio_wav_format(audio) + else: + audio = load_audio(audio) + assert isinstance(audio, + np.ndarray), f"Unsupported audio type: {type(audio)}" + duration = audio.shape[-1] / SAMPLE_RATE + audio = pad_or_trim(audio, N_SAMPLES) + audio = audio.astype(np.float32) + audio = torch.from_numpy(audio) + + if device is not None: + audio = audio.to(device) + if padding > 0: + audio = F.pad(audio, (0, padding)) + window = torch.hann_window(N_FFT).to(audio.device) + stft = torch.stft(audio, + N_FFT, + HOP_LENGTH, + window=window, + return_complex=True) + magnitudes = stft[..., :-1].abs()**2 + + filters = mel_filters(audio.device, n_mels, mel_filters_dir) + mel_spec = filters @ magnitudes + + log_spec = torch.clamp(mel_spec, min=1e-10).log10() + log_spec = torch.maximum(log_spec, log_spec.max() - 8.0) + log_spec = (log_spec + 4.0) / 4.0 + if return_duration: + return log_spec, duration + else: + return log_spec + + +def store_transcripts(filename: Pathlike, texts: Iterable[Tuple[str, str, + str]]) -> None: + """Save predicted results and reference transcripts to a file. + https://github.com/k2-fsa/icefall/blob/master/icefall/utils.py + Args: + filename: + File to save the results to. + texts: + An iterable of tuples. The first element is the cur_id, the second is + the reference transcript and the third element is the predicted result. + Returns: + Return None. + """ + with open(filename, "w") as f: + for cut_id, ref, hyp in texts: + print(f"{cut_id}:\tref={ref}", file=f) + print(f"{cut_id}:\thyp={hyp}", file=f) + + +def write_error_stats( + f: TextIO, + test_set_name: str, + results: List[Tuple[str, str]], + enable_log: bool = True, +) -> float: + """Write statistics based on predicted results and reference transcripts. + https://github.com/k2-fsa/icefall/blob/master/icefall/utils.py + It will write the following to the given file: + + - WER + - number of insertions, deletions, substitutions, corrects and total + reference words. For example:: + + Errors: 23 insertions, 57 deletions, 212 substitutions, over 2606 + reference words (2337 correct) + + - The difference between the reference transcript and predicted result. + An instance is given below:: + + THE ASSOCIATION OF (EDISON->ADDISON) ILLUMINATING COMPANIES + + The above example shows that the reference word is `EDISON`, + but it is predicted to `ADDISON` (a substitution error). + + Another example is:: + + FOR THE FIRST DAY (SIR->*) I THINK + + The reference word `SIR` is missing in the predicted + results (a deletion error). + results: + An iterable of tuples. The first element is the cur_id, the second is + the reference transcript and the third element is the predicted result. + enable_log: + If True, also print detailed WER to the console. + Otherwise, it is written only to the given file. + Returns: + Return None. + """ + subs: Dict[Tuple[str, str], int] = defaultdict(int) + ins: Dict[str, int] = defaultdict(int) + dels: Dict[str, int] = defaultdict(int) + + # `words` stores counts per word, as follows: + # corr, ref_sub, hyp_sub, ins, dels + words: Dict[str, List[int]] = defaultdict(lambda: [0, 0, 0, 0, 0]) + num_corr = 0 + ERR = "*" + for cut_id, ref, hyp in results: + ali = kaldialign.align(ref, hyp, ERR) + for ref_word, hyp_word in ali: + if ref_word == ERR: + ins[hyp_word] += 1 + words[hyp_word][3] += 1 + elif hyp_word == ERR: + dels[ref_word] += 1 + words[ref_word][4] += 1 + elif hyp_word != ref_word: + subs[(ref_word, hyp_word)] += 1 + words[ref_word][1] += 1 + words[hyp_word][2] += 1 + else: + words[ref_word][0] += 1 + num_corr += 1 + ref_len = sum([len(r) for _, r, _ in results]) + sub_errs = sum(subs.values()) + ins_errs = sum(ins.values()) + del_errs = sum(dels.values()) + tot_errs = sub_errs + ins_errs + del_errs + tot_err_rate = "%.2f" % (100.0 * tot_errs / ref_len) + + if enable_log: + logging.info(f"[{test_set_name}] %WER {tot_errs / ref_len:.2%} " + f"[{tot_errs} / {ref_len}, {ins_errs} ins, " + f"{del_errs} del, {sub_errs} sub ]") + + print(f"%WER = {tot_err_rate}", file=f) + print( + f"Errors: {ins_errs} insertions, {del_errs} deletions, " + f"{sub_errs} substitutions, over {ref_len} reference " + f"words ({num_corr} correct)", + file=f, + ) + print( + "Search below for sections starting with PER-UTT DETAILS:, " + "SUBSTITUTIONS:, DELETIONS:, INSERTIONS:, PER-WORD STATS:", + file=f, + ) + + print("", file=f) + print("PER-UTT DETAILS: corr or (ref->hyp) ", file=f) + for cut_id, ref, hyp in results: + ali = kaldialign.align(ref, hyp, ERR) + combine_successive_errors = True + if combine_successive_errors: + ali = [[[x], [y]] for x, y in ali] + for i in range(len(ali) - 1): + if ali[i][0] != ali[i][1] and ali[i + 1][0] != ali[i + 1][1]: + ali[i + 1][0] = ali[i][0] + ali[i + 1][0] + ali[i + 1][1] = ali[i][1] + ali[i + 1][1] + ali[i] = [[], []] + ali = [[ + list(filter(lambda a: a != ERR, x)), + list(filter(lambda a: a != ERR, y)), + ] for x, y in ali] + ali = list(filter(lambda x: x != [[], []], ali)) + ali = [[ + ERR if x == [] else " ".join(x), + ERR if y == [] else " ".join(y), + ] for x, y in ali] + + print( + f"{cut_id}:\t" + " ".join((ref_word if ref_word == hyp_word else + f"({ref_word}->{hyp_word})" + for ref_word, hyp_word in ali)), + file=f, + ) + + print("", file=f) + print("SUBSTITUTIONS: count ref -> hyp", file=f) + + for count, (ref, hyp) in sorted([(v, k) for k, v in subs.items()], + reverse=True): + print(f"{count} {ref} -> {hyp}", file=f) + + print("", file=f) + print("DELETIONS: count ref", file=f) + for count, ref in sorted([(v, k) for k, v in dels.items()], reverse=True): + print(f"{count} {ref}", file=f) + + print("", file=f) + print("INSERTIONS: count hyp", file=f) + for count, hyp in sorted([(v, k) for k, v in ins.items()], reverse=True): + print(f"{count} {hyp}", file=f) + + print("", file=f) + print("PER-WORD STATS: word corr tot_errs count_in_ref count_in_hyp", + file=f) + for _, word, counts in sorted([(sum(v[1:]), k, v) + for k, v in words.items()], + reverse=True): + (corr, ref_sub, hyp_sub, ins, dels) = counts + tot_errs = ref_sub + hyp_sub + ins + dels + ref_count = corr + ref_sub + dels + hyp_count = corr + hyp_sub + ins + + print(f"{word} {corr} {tot_errs} {ref_count} {hyp_count}", file=f) + return float(tot_err_rate) diff --git a/whisperfusion b/whisperfusion new file mode 160000 index 0000000000000000000000000000000000000000..1de4c740954848883f911e6c97e1db105b999b82 --- /dev/null +++ b/whisperfusion @@ -0,0 +1 @@ +Subproject commit 1de4c740954848883f911e6c97e1db105b999b82