abdwahdia commited on
Commit
0d82d3b
·
verified ·
1 Parent(s): e6a5c62

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +127 -0
app.py ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from transformers import BitsAndBytesConfig, LlavaNextVideoForConditionalGeneration, LlavaNextVideoProcessor
3
+ import torch
4
+ import av
5
+ import numpy as np
6
+ from huggingface_hub import hf_hub_download
7
+ from PIL import Image
8
+ import tempfile
9
+
10
+
11
+ # Configuration du modèle
12
+ quantization_config = BitsAndBytesConfig(
13
+ load_in_4bit=True,
14
+ bnb_4bit_compute_dtype=torch.float16,
15
+ llm_int8_enable_fp32_cpu_offload=True # Enable CPU offloading for unsupported layers
16
+ )
17
+
18
+
19
+ # Configuration du modèle
20
+ # quantization_config = BitsAndBytesConfig(
21
+ # load_in_4bit=True,
22
+ # bnb_4bit_compute_dtype=torch.float16
23
+ # )
24
+
25
+ processor = LlavaNextVideoProcessor.from_pretrained("llava-hf/LLaVA-NeXT-Video-7B-hf")
26
+ model = LlavaNextVideoForConditionalGeneration.from_pretrained(
27
+ "llava-hf/LLaVA-NeXT-Video-7B-hf",
28
+ quantization_config=quantization_config,
29
+ device_map='auto'
30
+ )
31
+
32
+ def read_video_pyav(container, indices):
33
+ frames = []
34
+ container.seek(0)
35
+ start_index = indices[0]
36
+ end_index = indices[-1]
37
+ for i, frame in enumerate(container.decode(video=0)):
38
+ if i > end_index:
39
+ break
40
+ if i >= start_index and i in indices:
41
+ frames.append(frame)
42
+ return np.stack([x.to_ndarray(format="rgb24") for x in frames])
43
+
44
+ def process_input(message, file):
45
+ # Vérifier le type de fichier
46
+ if file is None:
47
+ return "Veuillez uploader une image ou une vidéo"
48
+
49
+ if file.name.endswith(('.mp4', '.avi', '.mov')): # Traitement vidéo
50
+ with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as temp_video:
51
+ temp_video.write(open(file.name, "rb").read())
52
+ temp_video_path = temp_video.name
53
+
54
+ container = av.open(temp_video_path)
55
+ total_frames = container.streams.video[0].frames
56
+ indices = np.arange(0, total_frames, total_frames / 8).astype(int)
57
+ video_clip = read_video_pyav(container, indices)
58
+
59
+ conversation = [{
60
+ "role": "user",
61
+ "content": [
62
+ {"type": "text", "text": message},
63
+ {"type": "video"},
64
+ ],
65
+ }]
66
+
67
+ prompt = processor.apply_chat_template(conversation, add_generation_prompt=True)
68
+ inputs = processor([prompt], videos=[video_clip], padding=True, return_tensors="pt").to(model.device)
69
+
70
+ elif file.name.endswith(('.jpg', '.jpeg', '.png')): # Traitement image
71
+ image = Image.open(file.name)
72
+
73
+ conversation = [{
74
+ "role": "user",
75
+ "content": [
76
+ {"type": "text", "text": message},
77
+ {"type": "image"},
78
+ ],
79
+ }]
80
+
81
+ prompt = processor.apply_chat_template(conversation, add_generation_prompt=True)
82
+ inputs = processor(text=[prompt], images=[image], padding=True, return_tensors="pt").to(model.device)
83
+ else:
84
+ return "Format de fichier non supporté. Veuillez uploader une image ou une vidéo."
85
+
86
+ # Génération de la réponse
87
+ generate_kwargs = {"max_new_tokens": 1024, "do_sample": True, "top_p": 0.9}
88
+ output = model.generate(**inputs, **generate_kwargs)
89
+ generated_text = processor.batch_decode(output, skip_special_tokens=True)
90
+
91
+ return generated_text[0]
92
+
93
+ # Interface Gradio
94
+ with gr.Blocks(title="Chatbot Multimodal LLaVA") as demo:
95
+ gr.Markdown("# Chatbot Multimodal LLaVA")
96
+ gr.Markdown("Parlez avec un modèle IA capable de comprendre à la fois les images et les vidéos")
97
+
98
+ with gr.Row():
99
+ with gr.Column():
100
+ input_file = gr.File(label="Uploader une image ou une vidéo")
101
+ input_text = gr.Textbox(label="Votre message", placeholder="Posez votre question ici...")
102
+ submit_btn = gr.Button("Envoyer")
103
+
104
+ with gr.Column():
105
+ output_text = gr.Textbox(label="Réponse de l'IA", interactive=False)
106
+
107
+ submit_btn.click(
108
+ fn=process_input,
109
+ inputs=[input_text, input_file],
110
+ outputs=output_text
111
+ )
112
+
113
+ examples = [
114
+ ["Décris cette image en détail.", "/content/Psoriasis (1).jpg"],
115
+ ["Que se passe-t-il dans cette vidéo?", "/content/karate.mp4"],
116
+ ]
117
+
118
+ gr.Examples(
119
+ examples=examples,
120
+ inputs=[input_text, input_file],
121
+ outputs=output_text,
122
+ fn=process_input,
123
+ cache_examples=False
124
+ )
125
+
126
+ # Démarrer l'interface
127
+ demo.launch()