| 76 | print("downloading took: ", time.time() - start) |
| 77 | |
| 78 | class Predictor(BasePredictor): |
| 79 | def setup(self) -> None: |
| 80 | """Load the model into memory to make running multiple predictions efficient""" |
| 81 | for weight in weights: |
| 82 | download_weights(weight["src"], weight["dest"], weight["files"]) |
| 83 | disable_torch_init() |
| 84 | |
| 85 | self.tokenizer, self.model, self.image_processor, self.context_len = load_pretrained_model("liuhaotian/llava-v1.5-13b", model_name="llava-v1.5-13b", model_base=None, load_8bit=False, load_4bit=False) |
| 86 | |
| 87 | def predict( |
| 88 | self, |
| 89 | image: Path = Input(description="Input image"), |
| 90 | prompt: str = Input(description="Prompt to use for text generation"), |
| 91 | top_p: float = Input(description="When decoding text, samples from the top p percentage of most likely tokens; lower to ignore less likely tokens", ge=0.0, le=1.0, default=1.0), |
| 92 | temperature: float = Input(description="Adjusts randomness of outputs, greater than 1 is random and 0 is deterministic", default=0.2, ge=0.0), |
| 93 | max_tokens: int = Input(description="Maximum number of tokens to generate. A word is generally 2-3 tokens", default=1024, ge=0), |
| 94 | ) -> ConcatenateIterator[str]: |
| 95 | """Run a single prediction on the model""" |
| 96 | |
| 97 | conv_mode = "llava_v1" |
| 98 | conv = conv_templates[conv_mode].copy() |
| 99 | |
| 100 | image_data = load_image(str(image)) |
| 101 | image_tensor = self.image_processor.preprocess(image_data, return_tensors='pt')['pixel_values'].half().cuda() |
| 102 | |
| 103 | # loop start |
| 104 | |
| 105 | # just one turn, always prepend image token |
| 106 | inp = DEFAULT_IMAGE_TOKEN + '\n' + prompt |
| 107 | conv.append_message(conv.roles[0], inp) |
| 108 | |
| 109 | conv.append_message(conv.roles[1], None) |
| 110 | prompt = conv.get_prompt() |
| 111 | |
| 112 | input_ids = tokenizer_image_token(prompt, self.tokenizer, IMAGE_TOKEN_INDEX, return_tensors='pt').unsqueeze(0).cuda() |
| 113 | stop_str = conv.sep if conv.sep_style != SeparatorStyle.TWO else conv.sep2 |
| 114 | keywords = [stop_str] |
| 115 | streamer = TextIteratorStreamer(self.tokenizer, skip_prompt=True, timeout=20.0) |
| 116 | |
| 117 | with torch.inference_mode(): |
| 118 | thread = Thread(target=self.model.generate, kwargs=dict( |
| 119 | inputs=input_ids, |
| 120 | images=image_tensor, |
| 121 | do_sample=True, |
| 122 | temperature=temperature, |
| 123 | top_p=top_p, |
| 124 | max_new_tokens=max_tokens, |
| 125 | streamer=streamer, |
| 126 | use_cache=True)) |
| 127 | thread.start() |
| 128 | # workaround: second-to-last token is always " " |
| 129 | # but we want to keep it if it's not the second-to-last token |
| 130 | prepend_space = False |
| 131 | for new_text in streamer: |
| 132 | if new_text == " ": |
| 133 | prepend_space = True |
| 134 | continue |
| 135 | if new_text.endswith(stop_str): |
nothing calls this directly
no outgoing calls
no test coverage detected