Views
No views yet

transformers >= 4.42.0.
The model supports multi-visual and multi-prompt generation. Meaning that you can pass multiple images/videos in your prompt. Make sure also to follow the correct prompt template (USER: xxx\nASSISTANT:) and add the token <image> or <video> to the location where you want to query images/videos:float16 precision on a GPU device:1import av
2import torch
3import numpy as np
4from huggingface_hub import hf_hub_download
5from transformers import LlavaNextVideoProcessor, LlavaNextVideoForConditionalGeneration
6
7model_id = "llava-hf/LLaVA-NeXT-Video-7B-hf"
8
9model = LlavaNextVideoForConditionalGeneration.from_pretrained(
10 model_id,
11 torch_dtype=torch.float16,
12 low_cpu_mem_usage=True,
13).to(0)
14
15processor = LlavaNextVideoProcessor.from_pretrained(model_id)
16
17def read_video_pyav(container, indices):
18 '''
19 Decode the video with PyAV decoder.
20 Args:
21 container (`av.container.input.InputContainer`): PyAV container.
22 indices (`List[int]`): List of frame indices to decode.
23 Returns:
24 result (np.ndarray): np array of decoded frames of shape (num_frames, height, width, 3).
25 '''
26 frames = []
27 container.seek(0)
28 start_index = indices[0]
29 end_index = indices[-1]
30 for i, frame in enumerate(container.decode(video=0)):
31 if i > end_index:
32 break
33 if i >= start_index and i in indices:
34 frames.append(frame)
35 return np.stack([x.to_ndarray(format="rgb24") for x in frames])
36
37
38# define a chat history and use `apply_chat_template` to get correctly formatted prompt
39# Each value in "content" has to be a list of dicts with types ("text", "image", "video")
40conversation = [
41 {
42
43 "role": "user",
44 "content": [
45 {"type": "text", "text": "Why is this video funny?"},
46 {"type": "video"},
47 ],
48 },
49]
50
51prompt = processor.apply_chat_template(conversation, add_generation_prompt=True)
52
53video_path = hf_hub_download(repo_id="raushan-testing-hf/videos-test", filename="sample_demo_1.mp4", repo_type="dataset")
54container = av.open(video_path)
55
56# sample uniformly 8 frames from the video, can sample more for longer videos
57total_frames = container.streams.video[0].frames
58indices = np.arange(0, total_frames, total_frames / 8).astype(int)
59clip = read_video_pyav(container, indices)
60inputs_video = processor(text=prompt, videos=clip, padding=True, return_tensors="pt").to(model.device)
61
62output = model.generate(**inputs_video, max_new_tokens=100, do_sample=False)
63print(processor.decode(output[0][2:], skip_special_tokens=True))num_frames to sample from video, otherwise the whole video will be loaded.
Chat template will load the image/video for you and return inputs in torch.Tensor which you can pass directly to model.generate().1messages = [
2 {
3 "role": "user",
4 "content": [
5 {"type": "image", "url": "https://www.ilankelman.org/stopsigns/australia.jpg"}
6 {"type": "video", "path": "my_video.mp4"},
7 {"type": "text", "text": "What is shown in this image and video?"},
8 ],
9 },
10]
11
12inputs = processor.apply_chat_template(messages, num_frames=8, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors"pt")
13output = model.generate(**inputs, max_new_tokens=50)1import requests
2from PIL import Image
3
4conversation = [
5 {
6 "role": "user",
7 "content": [
8 {"type": "text", "text": "What are these?"},
9 {"type": "image"},
10 ],
11 },
12]
13prompt = processor.apply_chat_template(conversation, add_generation_prompt=True)
14
15image_file = "http://images.cocodataset.org/val2017/000000039769.jpg"
16raw_image = Image.open(requests.get(image_file, stream=True).raw)
17inputs_image = processor(text=prompt, images=raw_image, return_tensors='pt').to(0, torch.float16)
18
19output = model.generate(**inputs_video, max_new_tokens=100, do_sample=False)
20print(processor.decode(output[0][2:], skip_special_tokens=True))1conversation_1 = [
2 {
3 "role": "user",
4 "content": [
5 {"type": "text", "text": "What's the content of the image>"},
6 {"type": "image"},
7 ],
8 }
9]
10conversation_2 = [
11 {
12 "role": "user",
13 "content": [
14 {"type": "text", "text": "Why is this video funny?"},
15 {"type": "video"},
16 ],
17 },
18]
19prompt_1 = processor.apply_chat_template(conversation_1, add_generation_prompt=True)
20prompt_2 = processor.apply_chat_template(conversation_2, add_generation_prompt=True)
21
22s = processor(text=[prompt_1, prompt_2], images=image, videos=clip, padding=True, return_tensors="pt").to(model.device)
23
24# Generate
25generate_ids = model.generate(**inputs, max_new_tokens=100)
26out = processor.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)
27print(out)bitsandbytes librarybitsandbytes, pip install bitsandbytes and make sure to have access to a CUDA compatible GPU device. Simply change the snippet above with:1model = LlavaNextVideoForConditionalGeneration.from_pretrained(
2 model_id,
3 torch_dtype=torch.float16,
4 low_cpu_mem_usage=True,
5+ load_in_4bit=True
6)flash-attn. Refer to the original repository of Flash Attention regarding that package installation. Simply change the snippet above with:1model = LlavaNextVideoForConditionalGeneration.from_pretrained(
2 model_id,
3 torch_dtype=torch.float16,
4 low_cpu_mem_usage=True,
5+ use_flash_attention_2=True
6).to(0)1@misc{zhang2024llavanextvideo,
2 title={LLaVA-NeXT: A Strong Zero-shot Video Understanding Model},
3 url={https://llava-vl.github.io/blog/2024-04-30-llava-next-video/},
4 author={Zhang, Yuanhan and Li, Bo and Liu, haotian and Lee, Yong jae and Gui, Liangke and Fu, Di and Feng, Jiashi and Liu, Ziwei and Li, Chunyuan},
5 month={April},
6 year={2024}
7}1@misc{liu2024llavanext,
2 title={LLaVA-NeXT: Improved reasoning, OCR, and world knowledge},
3 url={https://llava-vl.github.io/blog/2024-01-30-llava-next/},
4 author={Liu, Haotian and Li, Chunyuan and Li, Yuheng and Li, Bo and Zhang, Yuanhan and Shen, Sheng and Lee, Yong Jae},
5 month={January},
6 year={2024}
7}