@@ -4227,6 +4227,126 @@ def __call__(self, **kwargs):
42274227 return super ().__call__ (** kwargs )
42284228
42294229
4230+ class PaddleOCRChatHandler (Llava15ChatHandler ):
4231+ """
4232+ Handler for PaddleOCR 1.5 multimodal models.
4233+ """
4234+
4235+ PADDLEOCR_CLS_TOKEN = "<|begin_of_sentence|>"
4236+ PADDLEOCR_BOS_TOKEN = "<s>"
4237+ PADDLEOCR_EOS_TOKEN = "</s>"
4238+ PADDLEOCR_SEP_TOKEN = "<|end_of_sentence|>"
4239+ PADDLEOCR_IMAGE_BOS_TOKEN = "<|IMAGE_START|>"
4240+ PADDLEOCR_IMAGE_EOS_TOKEN = "<|IMAGE_END|>"
4241+
4242+ CHAT_FORMAT = (
4243+ "{%- if not add_generation_prompt is defined -%}{%- set add_generation_prompt = true -%}{%- endif -%}"
4244+ "{%- if not cls_token is defined -%}{%- set cls_token = '" + PADDLEOCR_CLS_TOKEN + "' -%}{%- endif -%}"
4245+ "{%- if not eos_token is defined -%}{%- set eos_token = '" + PADDLEOCR_EOS_TOKEN + "' -%}{%- endif -%}"
4246+
4247+ "{{- cls_token -}}"
4248+ "{%- for message in messages -%}"
4249+ "{%- if message['role'] == 'user' -%}"
4250+ "{{- 'User: ' -}}"
4251+
4252+ # Robust parsing: Check if content is string or list
4253+ "{%- if message['content'] is string -%}"
4254+ "{{- message['content'] -}}"
4255+ "{%- else -%}"
4256+ # Pass 1: Render all images first
4257+ "{%- for content in message['content'] -%}"
4258+ "{%- if content['type'] == 'image_url' and 'image_url' in content -%}"
4259+ "{{- '<|IMAGE_START|>' -}}"
4260+ "{%- if content.image_url is string -%}"
4261+ "{{- content.image_url -}}"
4262+ "{%- else -%}"
4263+ "{{- content.image_url.url -}}"
4264+ "{%- endif -%}"
4265+ "{{- '<|IMAGE_END|>' -}}"
4266+ "{%- endif -%}"
4267+ "{%- endfor -%}"
4268+
4269+ # Pass 2: Render all text second
4270+ "{%- for content in message['content'] -%}"
4271+ "{%- if content['type'] == 'text' -%}"
4272+ "{{- content['text'] -}}"
4273+ "{%- endif -%}"
4274+ "{%- endfor -%}"
4275+ "{%- endif -%}"
4276+ "{{- '\\ n' -}}"
4277+
4278+ "{%- elif message['role'] == 'assistant' -%}"
4279+ "{{- 'Assistant:\\ n' -}}"
4280+ "{%- if message['content'] is string -%}"
4281+ "{{- message['content'] -}}"
4282+ "{%- else -%}"
4283+ "{%- for content in message['content'] -%}"
4284+ "{%- if content['type'] == 'text' -%}"
4285+ "{{- content['text'] -}}"
4286+ "{%- endif -%}"
4287+ "{%- endfor -%}"
4288+ "{%- endif -%}"
4289+ "{{- eos_token -}}"
4290+
4291+ "{%- elif message['role'] == 'system' -%}"
4292+ "{%- if message['content'] is string -%}"
4293+ "{{- message['content'] + '\\ n' -}}"
4294+ "{%- else -%}"
4295+ "{%- for content in message['content'] -%}"
4296+ "{%- if content['type'] == 'text' -%}"
4297+ "{{- content['text'] + '\\ n' -}}"
4298+ "{%- endif -%}"
4299+ "{%- endfor -%}"
4300+ "{%- endif -%}"
4301+ "{%- endif -%}"
4302+ "{%- endfor -%}"
4303+
4304+ "{%- if add_generation_prompt -%}"
4305+ "{{- 'Assistant:\\ n' -}}"
4306+ "{%- endif -%}"
4307+ )
4308+
4309+ def __init__ (
4310+ self ,
4311+ image_min_tokens : int = - 1 ,
4312+ image_max_tokens : int = - 1 ,
4313+ ** kwargs
4314+ ):
4315+ self .image_min_tokens = image_min_tokens
4316+ self .image_max_tokens = image_max_tokens
4317+ super ().__init__ (
4318+ image_min_tokens = self .image_min_tokens ,
4319+ image_max_tokens = self .image_max_tokens ,
4320+ ** kwargs
4321+ )
4322+
4323+ def __call__ (self , ** kwargs ):
4324+ # Set the specific stop token defined in the PaddleOCR template
4325+ kwargs ['stop' ] = [self .PADDLEOCR_EOS_TOKEN ]
4326+
4327+ llama = kwargs ['llama' ]
4328+ llama .reset ()
4329+ llama ._ctx .memory_clear (True )
4330+ llama .n_tokens = 0
4331+
4332+ if hasattr (llama , 'input_ids' ):
4333+ llama .input_ids .fill (0 )
4334+
4335+ if hasattr (self , '_last_image_embed' ):
4336+ self ._last_image_embed = None
4337+ self ._last_image_hash = None
4338+
4339+ if self .verbose :
4340+ messages = kwargs .get ('messages' , [])
4341+ try :
4342+ image_count = len (self .get_image_urls (messages ))
4343+ print (f"PaddleOCRChatHandler - Cleared state, Processing { image_count } images" , file = sys .stderr )
4344+ except Exception :
4345+ print (f"PaddleOCRChatHandler - Cleared state" , file = sys .stderr )
4346+
4347+ return super ().__call__ (** kwargs )
4348+
4349+
42304350class Qwen25VLChatHandler (Llava15ChatHandler ):
42314351 CHAT_FORMAT = (
42324352 "{% set image_count = namespace(value=0) %}"
0 commit comments