# Whisper chat ```elixir Mix.install( [ {:kino_bumblebee, "~> 0.2.1"}, {:exla, "~> 0.5.1"} ], config: [nx: [default_backend: EXLA.Backend]] ) ``` ## Section ```elixir Kino.Markdown.new(""" This chat is open to anyone, be polite and act responsibly. :) Note chat history has been disabled. """) ``` ```elixir {:ok, model_info} = Bumblebee.load_model({:hf, "openai/whisper-tiny"}, log_params_diff: false) {:ok, featurizer} = Bumblebee.load_featurizer({:hf, "openai/whisper-tiny"}) {:ok, tokenizer} = Bumblebee.load_tokenizer({:hf, "openai/whisper-tiny"}) serving = Bumblebee.Audio.speech_to_text(model_info, featurizer, tokenizer, max_new_tokens: 100, compile: [batch_size: 8], defn_options: [compiler: EXLA] ) Kino.start_child({Nx.Serving, serving: serving, name: WhisperChat}) ``` ```elixir audio_input = Kino.Input.audio("Audio", sampling_rate: featurizer.sampling_rate) name_input = Kino.Input.text("Name") form = Kino.Control.form([name: name_input, audio: audio_input], submit: "Send") frame = Kino.Frame.new() Kino.async_listen(form, fn %{data: %{audio: audio, name: name}, origin: origin} -> if audio && name != "" do audio = audio.data |> Nx.from_binary(:f32) |> Nx.reshape({:auto, audio.num_channels}) |> Nx.mean(axes: [1]) %{results: [%{text: generated_text}]} = Nx.Serving.batched_run(WhisperChat, audio) content = Kino.Markdown.new("**#{name}**: #{generated_text}") Kino.Frame.append(frame, content, temporary: true) else content = Kino.Markdown.new("*Error! Name and Audio are required*") Kino.Frame.append(frame, content, to: origin) end end) Kino.Layout.grid([frame, form], boxed: true, gap: 16) ```