@@ -403,10 +403,14 @@ def _generate_vision_language(case: TestCase, json_path: Path, device: str) -> N
403403 # Load images from testdata/
404404 images = [Image .open (Path ("testdata" ) / img_path ) for img_path in case .images ]
405405
406- # Build chat-formatted prompt with image placeholders if the
407- # processor supports apply_chat_template (Qwen-VL, Gemma-3, etc.)
406+ # Build chat-formatted prompt with image placeholders if the processor has a
407+ # usable chat template (Qwen-VL, Gemma-3, etc.). Base checkpoints (e.g.
408+ # google/gemma-4-12B) ship no chat template, so fall back to manually
409+ # prepending one image placeholder token per image — the processor then
410+ # expands each into the correct number of soft tokens (mirrors how
411+ # examples/gemma4_unified_ort_genai.py formats image prompts).
408412 prompt_text = case .prompts [0 ]
409- if hasattr (processor , "apply_chat_template" ):
413+ if getattr (processor , "chat_template" , None ):
410414 content : list [dict [str , str ]] = []
411415 for img_path in case .images :
412416 content .append ({"type" : "image" , "image" : str (Path ("testdata" ) / img_path )})
@@ -415,6 +419,8 @@ def _generate_vision_language(case: TestCase, json_path: Path, device: str) -> N
415419 prompt_text = processor .apply_chat_template (
416420 messages , tokenize = False , add_generation_prompt = True
417421 )
422+ elif getattr (processor , "image_token" , None ):
423+ prompt_text = processor .image_token * len (case .images ) + prompt_text
418424
419425 # Process multimodal inputs through the HF processor
420426 processed = processor (
@@ -739,7 +745,7 @@ def _prepare_speech_language_inputs(
739745 else :
740746 # Gemma4-style: text prompt + audio
741747 prompt_text = case .prompts [0 ]
742- if hasattr (processor , "apply_chat_template" ):
748+ if getattr (processor , "chat_template" , None ):
743749 content : list [dict [str , str ]] = [
744750 {"type" : "audio" , "audio" : str (audio_path )},
745751 {"type" : "text" , "text" : prompt_text },
@@ -748,6 +754,10 @@ def _prepare_speech_language_inputs(
748754 prompt_text = processor .apply_chat_template (
749755 messages , tokenize = False , add_generation_prompt = True
750756 )
757+ elif getattr (processor , "audio_token" , None ):
758+ # Base checkpoint (no chat template): manually prepend the audio
759+ # placeholder; the processor expands it to the right token count.
760+ prompt_text = processor .audio_token + prompt_text
751761 model_device = _get_model_device (model , device )
752762 processed = processor (
753763 text = prompt_text ,
0 commit comments