Files
Eric BuehlerandGitHub fff266550b Audio input support (Phi 4 multimodal) (#1448)
* Deps

* Add conformer

* Nemo loading

* Position embeds

* Load t5 attn bias

* Attn and feed forward

* Add conv module and glu pointwise

* Implement relative attn bias

* Add the forward methods

* Add encoder embedding

* Fix oproj

* Some loading

* Conformer loads!

* Fully loading speech stack

* Merger

* Dont need that

* First pass at audio processing

* Read samples

* Optional

* Small loading fix

* Runs but not correct yet

* Improved audio processing?

* Works with this

* Fix t5 attn bias

* It works!

* Comment

* Use some other crates

* Clippy

* Allow bf16 on metal

* Add prefix_audio

* Remove unused

* Typo

* User specified

* Add audio url parsing

* AudioProjectionMode -> InputMode

* Audio prefix caching

* Fix bug in audio prefix caching

* Support both at the same time!

* Tweak logging

* Support stereo

* Add mistralrs-audio

* Support batching

* Add server and rust api example

* Add python api

* Fix add_multimodal_message

* Fix unfold for conformer

* Streaming example

* Add web chat support

* Add modalities registry
2025-06-09 09:53:41 -04:00

62 lines
1.7 KiB
Rust

use std::io::Write;
use anyhow::Result;
use mistralrs::{
AudioInput, ChatCompletionChunkResponse, ChunkChoice, Delta, Response, TextMessageRole,
VisionMessages, VisionModelBuilder,
};
#[tokio::main]
async fn main() -> Result<()> {
let model = VisionModelBuilder::new("microsoft/Phi-4-multimodal-instruct")
.with_logging()
.build()
.await?;
let audio_bytes =
reqwest::get("https://upload.wikimedia.org/wikipedia/commons/4/42/Bird_singing.ogg")
.await?
.bytes()
.await?
.to_vec();
let audio = AudioInput::from_bytes(&audio_bytes)?;
let image_bytes =
reqwest::get("https://www.allaboutbirds.org/guide/assets/og/528129121-1200px.jpg")
.await?
.bytes()
.await?
.to_vec();
let image = image::load_from_memory(&image_bytes)?;
let messages = VisionMessages::new().add_multimodal_message(
TextMessageRole::User,
"Describe in detail what is happening.",
vec![image],
vec![audio],
&model,
)?;
let mut stream = model.stream_chat_request(messages).await?;
while let Some(chunk) = stream.next().await {
if let Response::Chunk(ChatCompletionChunkResponse { choices, .. }) = chunk {
if let Some(ChunkChoice {
delta:
Delta {
content: Some(content),
..
},
..
}) = choices.first()
{
print!("{content}");
std::io::stdout().flush()?;
};
} else {
// Handle errors
}
}
Ok(())
}