llama_runner/runner/
gemma4.rs1use crate::{
2 Gemma3VisionRunner, GenericVisionLmRequest, RunnerWithRecommendedSampling, VisionLmRunner,
3 error::{CreateLlamaCppRunnerError, GenericRunnerError},
4 sample::SimpleSamplingParams,
5 template::ChatTemplate,
6};
7
8pub const GEMMA_4_E2B_GUFF_MODEL_ID: &str = "unsloth/gemma-4-E2B-it-GGUF";
9pub const GEMMA_4_E2B_GUFF_MODEL_FILENAME: &str = "gemma-4-E2B-it-Q4_0.gguf";
10pub const GEMMA_4_E2B_GUFF_MULTIMODEL_FILENAME: &str = "mmproj-F16.gguf";
11
12#[repr(transparent)]
13pub struct Gemma4VisionRunner(Gemma3VisionRunner);
14
15impl Gemma4VisionRunner {
16 pub async fn default() -> Result<RunnerWithRecommendedSampling<Self>, CreateLlamaCppRunnerError>
17 {
18 let inner = Gemma3VisionRunner::new(
19 GEMMA_4_E2B_GUFF_MODEL_ID,
20 GEMMA_4_E2B_GUFF_MODEL_FILENAME,
21 GEMMA_4_E2B_GUFF_MULTIMODEL_FILENAME,
22 128_000u32.try_into().unwrap(),
23 )
24 .await?;
25 Ok(RunnerWithRecommendedSampling {
26 inner: Gemma4VisionRunner(inner),
27 default_sampling: SimpleSamplingParams {
28 top_p: Some(0.95f32),
29 top_k: Some(64),
30 temperature: Some(1.0f32),
31 presence_penalty: Some(1.5),
32 repetition_penalty: Some(1.0),
33 seed: None,
34 },
35 })
36 }
37}
38
39pub trait Gemma4ApplicableChatTemplate: ChatTemplate {}
40
41impl<'s, 'req, Tmpl: Gemma4ApplicableChatTemplate> VisionLmRunner<'s, 'req, Tmpl>
42 for Gemma4VisionRunner
43{
44 fn stream_vlm_response(
45 &'s self,
46 request: GenericVisionLmRequest<'req, Tmpl>,
47 ) -> impl Iterator<Item = Result<String, GenericRunnerError<Tmpl::Error>>> {
48 self.0.stream_vlm_response(request)
49 }
50}
51
52#[cfg(test)]
53mod test {
54 use crate::{mcp::Gemma4ChatTemplate, *};
55
56 #[tokio::test]
57 #[cfg(feature = "mcp")]
58 async fn test_vlm() {
59 let runner = Gemma4VisionRunner::default().await.unwrap();
60 let eiffel_tower_im =
61 image::load_from_memory(include_bytes!("../../assets/eiffel-tower.jpg")).unwrap();
62 let answer = runner
63 .get_vlm_response(GenericRunnerRequest {
64 messages: vec![
65 (
66 MessageRole::User,
67 ImageOrText::Text("Which city is this building in?"),
68 ),
69 (MessageRole::User, ImageOrText::Image(&eiffel_tower_im)),
70 ],
71 tmpl: Gemma4ChatTemplate::default(),
72 ..Default::default()
73 })
74 .unwrap();
75 assert!(answer.contains("Paris"));
76 }
77}