Norod78 commited on
Commit
ce3b288
ยท
verified ยท
1 Parent(s): d8963bb

hebrew_lyrics_generator-gemma3_4b

Browse files
Files changed (6) hide show
  1. .gitattributes +1 -0
  2. README.md +3 -3
  3. app.py +175 -0
  4. examples/image1.jpg +3 -0
  5. requirements.txt +7 -0
  6. style.css +17 -0
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ examples/image1.jpg filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -1,10 +1,10 @@
1
  ---
2
  title: Hebrew Lyrics Generator-gemma3 4b
3
- emoji: ๐ŸŒ
4
- colorFrom: gray
5
  colorTo: blue
6
  sdk: gradio
7
- sdk_version: 5.23.1
8
  app_file: app.py
9
  pinned: false
10
  license: apache-2.0
 
1
  ---
2
  title: Hebrew Lyrics Generator-gemma3 4b
3
+ emoji: ๐Ÿ‘ฉโ€๐ŸŽค
4
+ colorFrom: red
5
  colorTo: blue
6
  sdk: gradio
7
+ sdk_version: 5.14.0
8
  app_file: app.py
9
  pinned: false
10
  license: apache-2.0
app.py ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import cv2
3
+ import torch
4
+ from PIL import Image
5
+ from pathlib import Path
6
+ from threading import Thread
7
+ from transformers import AutoProcessor, Gemma3ForConditionalGeneration, TextIteratorStreamer
8
+ import spaces
9
+ import time
10
+
11
+ TITLE = " ืžื•ื“ืœ ืžื‘ื•ืกืก ื’ืžื” 3 ืœื™ืฆื™ืจืช ืฉื™ืจื™ื ืžื˜ื•ืคืฉื™ื ื‘ืขื‘ืจื™ืช "
12
+ DESCRIPTION= """
13
+ ื ื™ืชืŸ ืœื‘ืงืฉ ืฉื™ืจ ืขืœ ื‘ืกื™ืก ื˜ืงืกื˜, ืชืžื•ื ื” ื•ื•ื™ื“ืื•
14
+
15
+ [ื”ืžื•ื“ืœ ื–ืžื™ืŸ ืœื”ื•ืจื“ื”](https://huggingface.co/Norod78/gemma-3_4b_hebrew-lyrics-finetune)
16
+
17
+ ื”ืžื•ื“ืœ ื›ึผื•ึผื™ึทึผื™ืœ ืขืดื™ [ื“ื•ืจื•ืŸ ืื“ืœืจ](https://linktr.ee/Norod78)
18
+ """
19
+
20
+ # model config
21
+ model_4b_name = "Norod78/gemma-3_4b_hebrew-lyrics-finetune"
22
+ model_4b = Gemma3ForConditionalGeneration.from_pretrained(
23
+ model_4b_name,
24
+ device_map="auto",
25
+ torch_dtype=torch.bfloat16
26
+ ).eval()
27
+ processor_4b = AutoProcessor.from_pretrained(model_4b_name)
28
+ # I will add timestamp later
29
+ def extract_video_frames(video_path, num_frames=8):
30
+ cap = cv2.VideoCapture(video_path)
31
+ frames = []
32
+ total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
33
+ step = max(total_frames // num_frames, 1)
34
+
35
+ for i in range(num_frames):
36
+ cap.set(cv2.CAP_PROP_POS_FRAMES, i * step)
37
+ ret, frame = cap.read()
38
+ if ret:
39
+ frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
40
+ frames.append(Image.fromarray(frame))
41
+ cap.release()
42
+ return frames
43
+
44
+ def format_message(content, files):
45
+
46
+ message_content = []
47
+
48
+ if content:
49
+ parts = content.split('<image>')
50
+ for i, part in enumerate(parts):
51
+ if part.strip():
52
+ message_content.append({"type": "text", "text": part.strip()})
53
+ if i < len(parts) - 1 and files:
54
+ img = Image.open(files.pop(0))
55
+ message_content.append({"type": "image", "image": img})
56
+ for file in files:
57
+ file_path = file if isinstance(file, str) else file.name
58
+ if Path(file_path).suffix.lower() in ['.jpg', '.jpeg', '.png']:
59
+ img = Image.open(file_path)
60
+ message_content.append({"type": "image", "image": img})
61
+ elif Path(file_path).suffix.lower() in ['.mp4', '.mov']:
62
+ frames = extract_video_frames(file_path)
63
+ for frame in frames:
64
+ message_content.append({"type": "image", "image": frame})
65
+ return message_content
66
+
67
+ def format_conversation_history(chat_history):
68
+ messages = []
69
+ current_user_content = []
70
+ for item in chat_history:
71
+ role = item["role"]
72
+ content = item["content"]
73
+ if role == "user":
74
+ if isinstance(content, str):
75
+ current_user_content.append({"type": "text", "text": content})
76
+ elif isinstance(content, list):
77
+ current_user_content.extend(content)
78
+ else:
79
+ current_user_content.append({"type": "text", "text": str(content)})
80
+ elif role == "assistant":
81
+ if current_user_content:
82
+ messages.append({"role": "user", "content": current_user_content})
83
+ current_user_content = []
84
+ messages.append({"role": "assistant", "content": [{"type": "text", "text": str(content)}]})
85
+ if current_user_content:
86
+ messages.append({"role": "user", "content": current_user_content})
87
+ return messages
88
+
89
+ @spaces.GPU(duration=120)
90
+ def generate_response(input_data, chat_history, max_new_tokens, system_prompt, temperature, top_p, top_k, repetition_penalty):
91
+ if isinstance(input_data, dict) and "text" in input_data:
92
+ text = input_data["text"]
93
+ files = input_data.get("files", [])
94
+ else:
95
+ text = str(input_data)
96
+ files = []
97
+
98
+ new_message_content = format_message(text, files)
99
+ new_message = {"role": "user", "content": new_message_content}
100
+ system_message = [{"role": "system", "content": [{"type": "text", "text": system_prompt}]}] if system_prompt else []
101
+ processed_history = format_conversation_history(chat_history)
102
+ messages = system_message + processed_history
103
+ if messages and messages[-1]["role"] == "user":
104
+ messages[-1]["content"].extend(new_message["content"])
105
+ else:
106
+ messages.append(new_message)
107
+ model = model_4b
108
+ processor = processor_4b
109
+ inputs = processor.apply_chat_template(
110
+ messages,
111
+ add_generation_prompt=True,
112
+ tokenize=True,
113
+ return_tensors="pt",
114
+ return_dict=True
115
+ ).to(model.device)
116
+ streamer = TextIteratorStreamer(processor, skip_prompt=True, skip_special_tokens=True)
117
+ generation_kwargs = dict(
118
+ inputs,
119
+ streamer=streamer,
120
+ max_new_tokens=max_new_tokens,
121
+ do_sample=True,
122
+ temperature=temperature,
123
+ top_p=top_p,
124
+ top_k=top_k,
125
+ repetition_penalty=repetition_penalty
126
+ )
127
+ thread = Thread(target=model.generate, kwargs=generation_kwargs)
128
+ thread.start()
129
+
130
+ outputs = []
131
+ for text in streamer:
132
+ outputs.append(text)
133
+ yield "".join(outputs)
134
+
135
+ chat_interface = gr.ChatInterface(
136
+ fn=generate_response,
137
+ chatbot=gr.Chatbot(rtl=True, show_copy_button=True,type="messages"),
138
+ additional_inputs=[
139
+ gr.Slider(label="Max new tokens", minimum=100, maximum=2000, step=1, value=512),
140
+ gr.Textbox(
141
+ label="System Prompt",
142
+ value="ืืชื” ืžืฉื•ืจืจ ื™ืฉืจืืœื™, ื›ื•ืชื‘ ืฉื™ืจื™ื ื‘ืขื‘ืจื™ืช",
143
+ lines=4,
144
+ placeholder="ืฉื ื” ืืช ื”ื”ื’ื“ืจื•ืช ืฉืœ ื”ืžื•ื“ืœ",
145
+ text_align = 'right', rtl = True
146
+ ),
147
+ gr.Slider(label="Temperature", minimum=0.1, maximum=2.0, step=0.1, value=0.6),
148
+ gr.Slider(label="Top-p", minimum=0.05, maximum=1.0, step=0.05, value=0.92),
149
+ gr.Slider(label="Top-k", minimum=1, maximum=100, step=1, value=70),
150
+ gr.Slider(label="Repetition Penalty", minimum=1.0, maximum=2.0, step=0.05, value=1.1),
151
+ ],
152
+ examples=[
153
+ [{"text": "ื›ืชื•ื‘ ืœื™ ื‘ื‘ืงืฉื” ืฉื™ืจ ื”ืžืชืืจ ืืช ื”ืชืžื•ื ื”", "files": ["examples/image1.jpg"]}],
154
+ [{"text": "ืชืคื•ื— ืื“ืžื” ืขื ื—ืจื“ื” ื—ื‘ืจืชื™ืช"}]
155
+ ],
156
+ textbox=gr.MultimodalTextbox(
157
+ rtl=True,
158
+ label="ืงืœื˜",
159
+ file_types=["image", "video"],
160
+ file_count="multiple",
161
+ placeholder="ื‘ืงืฉื• ืฉื™ืจ ื•/ืื• ื”ืขืœื• ืชืžื•ื ื”",
162
+ ),
163
+ cache_examples=False,
164
+ type="messages",
165
+ fill_height=True,
166
+ stop_btn="ื”ืคืกืง",
167
+ css_paths=["style.css"],
168
+ multimodal=True,
169
+ title=TITLE,
170
+ description=DESCRIPTION,
171
+ theme=gr.themes.Soft(),
172
+ )
173
+
174
+ if __name__ == "__main__":
175
+ chat_interface.queue(max_size=20).launch()
examples/image1.jpg ADDED

Git LFS Details

  • SHA256: 344c337953e7b81a8aeef95d5249f4a8674a365299c33e3fc7811fce242013ab
  • Pointer size: 132 Bytes
  • Size of remote file: 3.44 MB
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ transformers
2
+ spaces
3
+ torch
4
+ transformers @ git+https://github.com/huggingface/[email protected]
5
+ pillow
6
+ opencv-python-headless
7
+ accelerate
style.css ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ h1 {
2
+ text-align: center;
3
+ display: block;
4
+ }
5
+
6
+ #duplicate-button {
7
+ margin: auto;
8
+ color: white;
9
+ background: #1565c0;
10
+ border-radius: 100vh;
11
+ }
12
+
13
+ .contain {
14
+ max-width: 900px;
15
+ margin: auto;
16
+ padding-top: 1.5rem;
17
+ }