code: def generate_stream(self, params):
      tokenizer, model, image_processor = (
          self.tokenizer,
          self.model,
          self.image_processor,
      )
  
      image_w = self.image_w
      image_h = self.image_h
      prompt = params["prompt"]
      ori_prompt = prompt
      region_masks = params.get("region_masks", None)
  
      images = params.get("images", None)
      num_image_tokens = 0
      if images is not None and len(images) > 0 and self.is_multimodal:
          if len(images) > 0:
              if len(images) != prompt.count(DEFAULT_IMAGE_TOKEN):
                  raise ValueError(
                      "Number of images does not match number of <image> tokens in prompt"
                  )
  
              images = [
                  load_image_from_base64(image) for image in images
              ]
              if self.keep_aspect_ratio:
                  images = process_images(
                      images, image_processor, model.config
                  )
              else:
                  images = image_processor(
                      images,
                      return_tensors="pt",
                      do_resize=True,
                      do_center_crop=False,
                      size=[image_h, image_w],
                  )["pixel_values"]
  
              if type(images) is list:
                  images = [
                      image.to(self.model.device, dtype=torch.float16)
                      for image in images
                  ]
              else:
                  images = images.to(
                      self.model.device, dtype=torch.float16
                  )
  
              replace_token = DEFAULT_IMAGE_TOKEN
              if getattr(
                  self.model.config, "mm_use_im_start_end", False
              ):
                  replace_token = (
                      DEFAULT_IM_START_TOKEN
                      + replace_token
                      + DEFAULT_IM_END_TOKEN
                  )
              prompt = prompt.replace(
                  DEFAULT_IMAGE_TOKEN, replace_token
              )
  
              num_image_tokens = (
                  prompt.count(replace_token)
                  * model.get_vision_tower().num_patches
              )
          else:
              images = None
          image_args = {"images": images}
      else:
          images = None
          image_args = {}
  
      if region_masks is not None:
          assert self.add_region_feature
          region_masks = [
              [
                  torch.Tensor(region_mask_i).cuda().half()
                  for region_mask_i in region_masks
              ]
          ]
          image_args["region_masks"] = region_masks
          logger.info("Add region_masks to image_args.")
      else:
          logger.info("No region_masks for this sample.")
          region_masks = None
  
      l_prompt = len(prompt)
      temperature = float(params.get("temperature", 1.0))
      top_p = float(params.get("top_p", 1.0))
      max_context_length = getattr(
          model.config, "max_position_embeddings", 2048
      )
      max_new_tokens = min(int(params.get("max_new_tokens", 256)), 1024)
      stop_str = params.get("stop", None)
  
      stop_idx = None
      if stop_str is not None:
          stop_idx = tokenizer(stop_str).input_ids
          if len(stop_idx) == 1:
              stop_idx = stop_idx[0]
          else:
              stop_idx = None
  
      # input_ids = tokenizer(prompt).input_ids
      input_ids = tokenizer_image_token(
          prompt, tokenizer, IMAGE_TOKEN_INDEX, return_tensors=None
      )
      output_ids = list(input_ids)
      pred_ids = []
  
      max_src_len = self.context_len - max_new_tokens - 8
      input_ids = input_ids[-max_src_len:]
  
      past_key_values = None
      for i in range(max_new_tokens):
          if i == 0:
              out = model(
                  torch.as_tensor([input_ids]).cuda(),
                  use_cache=True,
                  **image_args,
              )
              logits = out.logits
              past_key_values = out.past_key_values
          else:
              attention_mask = torch.ones(
                  1, past_key_values[0][0].shape[-2] + 1, device="cuda"
              )
              out = model(
                  input_ids=torch.as_tensor([[token]], device="cuda"),
                  use_cache=True,
                  attention_mask=attention_mask,
                  past_key_values=past_key_values,
                  region_masks=region_masks,
              )
              logits = out.logits
              past_key_values = out.past_key_values
  
          last_token_logits = logits[0][-1]
          if temperature < 1e-4:
              token = int(torch.argmax(last_token_logits))
          else:
              probs = torch.softmax(
                  last_token_logits / temperature, dim=-1
              )
              token = int(torch.multinomial(probs, num_samples=1))
  
          output_ids.append(token)
          pred_ids.append(token)
  
          if stop_idx is not None and token == stop_idx:
              stopped = True
          elif token == tokenizer.eos_token_id:
              stopped = True
          else:
              stopped = False
  
          if (
              i % args.stream_interval == 0
              or i == max_new_tokens - 1
              or stopped
          ):
              cur_out = tokenizer.decode(
                  pred_ids, skip_special_tokens=True
              )
              pos = cur_out.rfind(stop_str)
              if pos != -1:
                  cur_out = cur_out[:pos]
                  stopped = True
              output = ori_prompt + cur_out
  
              ret = {
                  "text": output,
                  "error_code": 0,
              }
              yield json.dumps(ret).encode() + b"\0"
  
          if stopped:
              break
  
      if past_key_values is not None:
          del past_key_values
  
imports: import argparse
  import asyncio
  import json
  import time
  import threading
  import uuid
  from fastapi import FastAPI, Request, BackgroundTasks
  from fastapi.responses import StreamingResponse
  import requests
  import torch
  import uvicorn
  from functools import partial
  from ferret.constants import WORKER_HEART_BEAT_INTERVAL
  from ferret.utils import build_logger, server_error_msg, pretty_print_semaphore
  from ferret.model.builder import load_pretrained_model
  from ferret.mm_utils import process_images, load_image_from_base64, tokenizer_image_token, KeywordsStoppingCriteria
  from ferret.constants import IMAGE_TOKEN_INDEX, DEFAULT_IMAGE_TOKEN, DEFAULT_IM_START_TOKEN, DEFAULT_IM_END_TOKEN
  from threading import Thread
label_desc: Use image node_id 6 for calling the ModelWorker obj's underlying member method code with example usage: obj.generate_stream(params) without return types