hysts HF Staff commited on
Commit
01e4a7b
·
1 Parent(s): e0e3138
.gitattributes CHANGED
@@ -33,3 +33,7 @@ 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
+ *.jpeg filter=lfs diff=lfs merge=lfs -text
37
+ *.whl filter=lfs diff=lfs merge=lfs -text
38
+ *.wav filter=lfs diff=lfs merge=lfs -text
39
+ *.jpg filter=lfs diff=lfs merge=lfs -text
.pre-commit-config.yaml ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v5.0.0
4
+ hooks:
5
+ - id: check-executables-have-shebangs
6
+ - id: check-json
7
+ - id: check-merge-conflict
8
+ - id: check-shebang-scripts-are-executable
9
+ - id: check-toml
10
+ - id: check-yaml
11
+ - id: end-of-file-fixer
12
+ - id: mixed-line-ending
13
+ args: ["--fix=lf"]
14
+ - id: requirements-txt-fixer
15
+ - id: trailing-whitespace
16
+ - repo: https://github.com/astral-sh/ruff-pre-commit
17
+ rev: v0.12.0
18
+ hooks:
19
+ - id: ruff-check
20
+ args: ["--fix"]
21
+ - id: ruff-format
22
+ - repo: https://github.com/pre-commit/mirrors-mypy
23
+ rev: v1.16.1
24
+ hooks:
25
+ - id: mypy
26
+ args: ["--ignore-missing-imports"]
27
+ additional_dependencies:
28
+ [
29
+ "types-python-slugify",
30
+ "types-pytz",
31
+ "types-PyYAML",
32
+ "types-requests",
33
+ ]
.python-version ADDED
@@ -0,0 +1 @@
 
 
1
+ 3.10
.vscode/extensions.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "recommendations": [
3
+ "ms-python.python",
4
+ "charliermarsh.ruff",
5
+ "streetsidesoftware.code-spell-checker",
6
+ "tamasfe.even-better-toml"
7
+ ]
8
+ }
.vscode/settings.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "editor.formatOnSave": true,
3
+ "files.insertFinalNewline": false,
4
+ "[python]": {
5
+ "editor.defaultFormatter": "charliermarsh.ruff",
6
+ "editor.formatOnType": true,
7
+ "editor.codeActionsOnSave": {
8
+ "source.fixAll.ruff": "explicit",
9
+ "source.organizeImports": "explicit"
10
+ }
11
+ },
12
+ "[jupyter]": {
13
+ "files.insertFinalNewline": false
14
+ },
15
+ "notebook.output.scrolling": true,
16
+ "notebook.formatOnSave.enabled": true
17
+ }
README.md CHANGED
@@ -1,8 +1,8 @@
1
  ---
2
  title: Gemma 3n E4B It
3
- emoji: 🦀
4
- colorFrom: purple
5
- colorTo: pink
6
  sdk: gradio
7
  sdk_version: 5.34.2
8
  app_file: app.py
 
1
  ---
2
  title: Gemma 3n E4B It
3
+ emoji:
4
+ colorFrom: red
5
+ colorTo: purple
6
  sdk: gradio
7
  sdk_version: 5.34.2
8
  app_file: app.py
app.py ADDED
@@ -0,0 +1,260 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import pathlib
3
+ import shlex
4
+ import subprocess
5
+ import tempfile
6
+ from collections.abc import Iterator
7
+ from threading import Thread
8
+
9
+ # TODO: remove this once the transformers implementation is published # noqa: FIX002, TD002, TD003
10
+ if os.getenv("SPACE_ID"):
11
+ subprocess.run(shlex.split("pip install wheels/timm-1.0.16.dev0-py3-none-any.whl"), check=True) # noqa: S603
12
+ subprocess.run(shlex.split("pip install wheels/transformers-4.53.0.dev0-py3-none-any.whl"), check=True) # noqa: S603
13
+
14
+ import av
15
+ import gradio as gr
16
+ import spaces
17
+ import torch
18
+ from gradio.utils import get_upload_folder
19
+ from transformers import AutoModelForImageTextToText, AutoProcessor
20
+ from transformers.generation.streamers import TextIteratorStreamer
21
+
22
+ # TODO: update model_id # noqa: FIX002, TD002, TD003
23
+ model_id = "gg-hf-gm/gemma-3n-E4B-it"
24
+
25
+ processor = AutoProcessor.from_pretrained(model_id)
26
+ model = AutoModelForImageTextToText.from_pretrained(model_id, device_map="auto", torch_dtype=torch.bfloat16)
27
+
28
+ IMAGE_FILE_TYPES = (".jpg", ".jpeg", ".png", ".webp")
29
+ VIDEO_FILE_TYPES = (".mp4", ".mov", ".webm")
30
+ AUDIO_FILE_TYPES = (".mp3", ".wav")
31
+
32
+ GRADIO_TEMP_DIR = get_upload_folder()
33
+
34
+ TARGET_FPS = int(os.getenv("TARGET_FPS", "3"))
35
+ MAX_FRAMES = int(os.getenv("MAX_FRAMES", "30"))
36
+ MAX_INPUT_TOKENS = int(os.getenv("MAX_INPUT_TOKENS", "10_000"))
37
+
38
+
39
+ def get_file_type(path: str) -> str:
40
+ if path.endswith(IMAGE_FILE_TYPES):
41
+ return "image"
42
+ if path.endswith(VIDEO_FILE_TYPES):
43
+ return "video"
44
+ if path.endswith(AUDIO_FILE_TYPES):
45
+ return "audio"
46
+ error_message = f"Unsupported file type: {path}"
47
+ raise ValueError(error_message)
48
+
49
+
50
+ def count_files_in_new_message(paths: list[str]) -> tuple[int, int]:
51
+ video_count = 0
52
+ non_video_count = 0
53
+ for path in paths:
54
+ if path.endswith(VIDEO_FILE_TYPES):
55
+ video_count += 1
56
+ else:
57
+ non_video_count += 1
58
+ return video_count, non_video_count
59
+
60
+
61
+ def validate_media_constraints(message: dict) -> bool:
62
+ video_count, non_video_count = count_files_in_new_message(message["files"])
63
+ if video_count > 1:
64
+ gr.Warning("Only one video is supported.")
65
+ return False
66
+ if video_count == 1 and non_video_count > 0:
67
+ gr.Warning("Mixing images and videos is not allowed.")
68
+ return False
69
+ return True
70
+
71
+
72
+ def extract_frames_to_tempdir(
73
+ video_path: str,
74
+ target_fps: float,
75
+ max_frames: int | None = None,
76
+ parent_dir: str | None = None,
77
+ prefix: str = "frames_",
78
+ ) -> str:
79
+ temp_dir = tempfile.mkdtemp(prefix=prefix, dir=parent_dir)
80
+
81
+ container = av.open(video_path)
82
+ video_stream = container.streams.video[0]
83
+
84
+ if video_stream.duration is None or video_stream.time_base is None:
85
+ raise ValueError("video_stream is missing duration or time_base")
86
+
87
+ time_base = video_stream.time_base
88
+ duration = float(video_stream.duration * time_base)
89
+ interval = 1.0 / target_fps
90
+
91
+ total_frames = int(duration * target_fps)
92
+ if max_frames is not None:
93
+ total_frames = min(total_frames, max_frames)
94
+
95
+ target_times = [i * interval for i in range(total_frames)]
96
+ target_index = 0
97
+
98
+ for frame in container.decode(video=0):
99
+ if frame.pts is None:
100
+ continue
101
+
102
+ timestamp = float(frame.pts * time_base)
103
+
104
+ if target_index < len(target_times) and abs(timestamp - target_times[target_index]) < (interval / 2):
105
+ frame_path = pathlib.Path(temp_dir) / f"frame_{target_index:04d}.jpg"
106
+ frame.to_image().save(frame_path)
107
+ target_index += 1
108
+
109
+ if max_frames is not None and target_index >= max_frames:
110
+ break
111
+
112
+ container.close()
113
+ return temp_dir
114
+
115
+
116
+ def process_new_user_message(message: dict) -> list[dict]:
117
+ if not message["files"]:
118
+ return [{"type": "text", "text": message["text"]}]
119
+
120
+ file_types = [get_file_type(path) for path in message["files"]]
121
+
122
+ if len(file_types) == 1 and file_types[0] == "video":
123
+ gr.Info(f"Video will be processed at {TARGET_FPS} FPS, max {MAX_FRAMES} frames in this Space.")
124
+
125
+ temp_dir = extract_frames_to_tempdir(
126
+ message["files"][0],
127
+ target_fps=TARGET_FPS,
128
+ max_frames=MAX_FRAMES,
129
+ parent_dir=GRADIO_TEMP_DIR,
130
+ )
131
+ paths = sorted(pathlib.Path(temp_dir).glob("*.jpg"))
132
+ return [
133
+ {"type": "text", "text": message["text"]},
134
+ *[{"type": "image", "image": path.as_posix()} for path in paths],
135
+ ]
136
+
137
+ return [
138
+ {"type": "text", "text": message["text"]},
139
+ *[{"type": file_type, file_type: path} for path, file_type in zip(message["files"], file_types, strict=True)],
140
+ ]
141
+
142
+
143
+ def process_history(history: list[dict]) -> list[dict]:
144
+ messages = []
145
+ current_user_content: list[dict] = []
146
+ for item in history:
147
+ if item["role"] == "assistant":
148
+ if current_user_content:
149
+ messages.append({"role": "user", "content": current_user_content})
150
+ current_user_content = []
151
+ messages.append({"role": "assistant", "content": [{"type": "text", "text": item["content"]}]})
152
+ else:
153
+ content = item["content"]
154
+ if isinstance(content, str):
155
+ current_user_content.append({"type": "text", "text": content})
156
+ else:
157
+ filepath = content[0]
158
+ file_type = get_file_type(filepath)
159
+ current_user_content.append({"type": file_type, file_type: filepath})
160
+ return messages
161
+
162
+
163
+ @spaces.GPU(duration=120)
164
+ @torch.inference_mode()
165
+ def generate(message: dict, history: list[dict], system_prompt: str = "", max_new_tokens: int = 512) -> Iterator[str]:
166
+ if not validate_media_constraints(message):
167
+ yield ""
168
+ return
169
+
170
+ messages = []
171
+ if system_prompt:
172
+ messages.append({"role": "system", "content": [{"type": "text", "text": system_prompt}]})
173
+ messages.extend(process_history(history))
174
+ messages.append({"role": "user", "content": process_new_user_message(message)})
175
+
176
+ inputs = processor.apply_chat_template(
177
+ messages,
178
+ add_generation_prompt=True,
179
+ tokenize=True,
180
+ return_dict=True,
181
+ return_tensors="pt",
182
+ )
183
+ n_tokens = inputs["input_ids"].shape[1]
184
+ if n_tokens > MAX_INPUT_TOKENS:
185
+ gr.Warning(
186
+ f"Input too long. Max {MAX_INPUT_TOKENS} tokens. Got {n_tokens} tokens. This limit is set to avoid CUDA out-of-memory errors in this Space."
187
+ )
188
+ yield ""
189
+ return
190
+
191
+ inputs = inputs.to(device=model.device, dtype=torch.bfloat16)
192
+
193
+ streamer = TextIteratorStreamer(processor, timeout=30.0, skip_prompt=True, skip_special_tokens=True)
194
+ generate_kwargs = dict(
195
+ inputs,
196
+ streamer=streamer,
197
+ max_new_tokens=max_new_tokens,
198
+ do_sample=False,
199
+ disable_compile=True,
200
+ )
201
+ t = Thread(target=model.generate, kwargs=generate_kwargs)
202
+ t.start()
203
+
204
+ output = ""
205
+ for delta in streamer:
206
+ output += delta
207
+ yield output
208
+
209
+
210
+ examples = [
211
+ [
212
+ {
213
+ "text": "What is the capital of France?",
214
+ "files": [],
215
+ }
216
+ ],
217
+ [
218
+ {
219
+ "text": "Describe this image in detail.",
220
+ "files": ["assets/cat.jpeg"],
221
+ }
222
+ ],
223
+ [
224
+ {
225
+ "text": "Transcribe the following speech segment in English.",
226
+ "files": ["assets/speech.wav"],
227
+ }
228
+ ],
229
+ [
230
+ {
231
+ "text": "Transcribe the following speech segment in English.",
232
+ "files": ["assets/speech2.wav"],
233
+ }
234
+ ],
235
+ ]
236
+
237
+ demo = gr.ChatInterface(
238
+ fn=generate,
239
+ type="messages",
240
+ textbox=gr.MultimodalTextbox(
241
+ file_types=list(IMAGE_FILE_TYPES + VIDEO_FILE_TYPES + AUDIO_FILE_TYPES),
242
+ file_count="multiple",
243
+ autofocus=True,
244
+ ),
245
+ multimodal=True,
246
+ additional_inputs=[
247
+ gr.Textbox(label="System Prompt", value="You are a helpful assistant."),
248
+ gr.Slider(label="Max New Tokens", minimum=100, maximum=2000, step=10, value=700),
249
+ ],
250
+ stop_btn=False,
251
+ title="Gemma 3n E4B it",
252
+ examples=examples,
253
+ run_examples_on_click=False,
254
+ cache_examples=False,
255
+ css_paths="style.css",
256
+ delete_cache=(1800, 1800),
257
+ )
258
+
259
+ if __name__ == "__main__":
260
+ demo.launch()
assets/cat.jpeg ADDED

Git LFS Details

  • SHA256: 4f4820fd544a706efeca9ad723e0b2185d802ebdc2d719c6823b2340eda0e554
  • Pointer size: 130 Bytes
  • Size of remote file: 90.7 kB
assets/speech.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:219f55927c62af71fa7dc29581b647ade375286498dd0e342cc07c72cc8edc04
3
+ size 136764
assets/speech2.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f03711ca239a7b6f3cd13f3942f4f64b32173f4f1d01abf55fa91608a178efac
3
+ size 545644
pyproject.toml ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [project]
2
+ name = "gemma-3n-e4b-it"
3
+ version = "0.1.0"
4
+ description = ""
5
+ readme = "README.md"
6
+ requires-python = ">=3.10"
7
+ dependencies = [
8
+ "accelerate>=1.8.1",
9
+ "av>=14.4.0",
10
+ "gradio>=5.34.2",
11
+ "hf-transfer>=0.1.9",
12
+ "librosa>=0.11.0",
13
+ "spaces>=0.37.1",
14
+ "torch==2.5.1",
15
+ "torchvision>=0.20.1",
16
+ ]
17
+
18
+ [tool.ruff]
19
+ line-length = 119
20
+
21
+ [tool.ruff.lint]
22
+ select = ["ALL"]
23
+ ignore = [
24
+ "COM812", # missing-trailing-comma
25
+ "D203", # one-blank-line-before-class
26
+ "D213", # multi-line-summary-second-line
27
+ "E501", # line-too-long
28
+ "SIM117", # multiple-with-statements
29
+ #
30
+ "D100", # undocumented-public-module
31
+ "D101", # undocumented-public-class
32
+ "D102", # undocumented-public-method
33
+ "D103", # undocumented-public-function
34
+ "D104", # undocumented-public-package
35
+ "D105", # undocumented-magic-method
36
+ "D107", # undocumented-public-init
37
+ "EM101", # raw-string-in-exception
38
+ "FBT001", # boolean-type-hint-positional-argument
39
+ "FBT002", # boolean-default-value-positional-argument
40
+ "PD901", # pandas-df-variable-name
41
+ "PGH003", # blanket-type-ignore
42
+ "PLR0913", # too-many-arguments
43
+ "PLR0915", # too-many-statements
44
+ "TRY003", # raise-vanilla-args
45
+ ]
46
+ unfixable = [
47
+ "F401", # unused-import
48
+ ]
49
+
50
+ [tool.ruff.lint.pydocstyle]
51
+ convention = "google"
52
+
53
+ [tool.ruff.lint.per-file-ignores]
54
+ "*.ipynb" = ["T201", "T203"]
55
+
56
+ [tool.ruff.format]
57
+ docstring-code-format = true
58
+
59
+ [tool.uv.sources]
60
+ timm = { path = "wheels/timm-1.0.16.dev0-py3-none-any.whl" }
61
+ transformers = { path = "wheels/transformers-4.53.0.dev0-py3-none-any.whl" }
62
+
63
+ [dependency-groups]
64
+ dev = [
65
+ "timm",
66
+ "transformers",
67
+ ]
requirements.txt ADDED
@@ -0,0 +1,288 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file was autogenerated by uv via the following command:
2
+ # uv pip compile pyproject.toml -o requirements.txt
3
+ accelerate==1.8.1
4
+ # via gemma-3n-e4b-it (pyproject.toml)
5
+ aiofiles==24.1.0
6
+ # via gradio
7
+ annotated-types==0.7.0
8
+ # via pydantic
9
+ anyio==4.9.0
10
+ # via
11
+ # gradio
12
+ # httpx
13
+ # starlette
14
+ audioread==3.0.1
15
+ # via librosa
16
+ av==14.4.0
17
+ # via gemma-3n-e4b-it (pyproject.toml)
18
+ certifi==2025.6.15
19
+ # via
20
+ # httpcore
21
+ # httpx
22
+ # requests
23
+ cffi==1.17.1
24
+ # via soundfile
25
+ charset-normalizer==3.4.2
26
+ # via requests
27
+ click==8.2.1
28
+ # via
29
+ # typer
30
+ # uvicorn
31
+ decorator==5.2.1
32
+ # via librosa
33
+ exceptiongroup==1.3.0
34
+ # via anyio
35
+ fastapi==0.115.13
36
+ # via gradio
37
+ ffmpy==0.6.0
38
+ # via gradio
39
+ filelock==3.18.0
40
+ # via
41
+ # huggingface-hub
42
+ # torch
43
+ # triton
44
+ fsspec==2025.5.1
45
+ # via
46
+ # gradio-client
47
+ # huggingface-hub
48
+ # torch
49
+ gradio==5.34.2
50
+ # via
51
+ # gemma-3n-e4b-it (pyproject.toml)
52
+ # spaces
53
+ gradio-client==1.10.3
54
+ # via gradio
55
+ groovy==0.1.2
56
+ # via gradio
57
+ h11==0.16.0
58
+ # via
59
+ # httpcore
60
+ # uvicorn
61
+ hf-transfer==0.1.9
62
+ # via gemma-3n-e4b-it (pyproject.toml)
63
+ hf-xet==1.1.5
64
+ # via huggingface-hub
65
+ httpcore==1.0.9
66
+ # via httpx
67
+ httpx==0.28.1
68
+ # via
69
+ # gradio
70
+ # gradio-client
71
+ # safehttpx
72
+ # spaces
73
+ huggingface-hub==0.33.0
74
+ # via
75
+ # accelerate
76
+ # gradio
77
+ # gradio-client
78
+ idna==3.10
79
+ # via
80
+ # anyio
81
+ # httpx
82
+ # requests
83
+ jinja2==3.1.6
84
+ # via
85
+ # gradio
86
+ # torch
87
+ joblib==1.5.1
88
+ # via
89
+ # librosa
90
+ # scikit-learn
91
+ lazy-loader==0.4
92
+ # via librosa
93
+ librosa==0.11.0
94
+ # via gemma-3n-e4b-it (pyproject.toml)
95
+ llvmlite==0.44.0
96
+ # via numba
97
+ markdown-it-py==3.0.0
98
+ # via rich
99
+ markupsafe==3.0.2
100
+ # via
101
+ # gradio
102
+ # jinja2
103
+ mdurl==0.1.2
104
+ # via markdown-it-py
105
+ mpmath==1.3.0
106
+ # via sympy
107
+ msgpack==1.1.1
108
+ # via librosa
109
+ networkx==3.4.2
110
+ # via torch
111
+ numba==0.61.2
112
+ # via librosa
113
+ numpy==2.2.6
114
+ # via
115
+ # accelerate
116
+ # gradio
117
+ # librosa
118
+ # numba
119
+ # pandas
120
+ # scikit-learn
121
+ # scipy
122
+ # soundfile
123
+ # soxr
124
+ # torchvision
125
+ nvidia-cublas-cu12==12.4.5.8
126
+ # via
127
+ # nvidia-cudnn-cu12
128
+ # nvidia-cusolver-cu12
129
+ # torch
130
+ nvidia-cuda-cupti-cu12==12.4.127
131
+ # via torch
132
+ nvidia-cuda-nvrtc-cu12==12.4.127
133
+ # via torch
134
+ nvidia-cuda-runtime-cu12==12.4.127
135
+ # via torch
136
+ nvidia-cudnn-cu12==9.1.0.70
137
+ # via torch
138
+ nvidia-cufft-cu12==11.2.1.3
139
+ # via torch
140
+ nvidia-curand-cu12==10.3.5.147
141
+ # via torch
142
+ nvidia-cusolver-cu12==11.6.1.9
143
+ # via torch
144
+ nvidia-cusparse-cu12==12.3.1.170
145
+ # via
146
+ # nvidia-cusolver-cu12
147
+ # torch
148
+ nvidia-nccl-cu12==2.21.5
149
+ # via torch
150
+ nvidia-nvjitlink-cu12==12.4.127
151
+ # via
152
+ # nvidia-cusolver-cu12
153
+ # nvidia-cusparse-cu12
154
+ # torch
155
+ nvidia-nvtx-cu12==12.4.127
156
+ # via torch
157
+ orjson==3.10.18
158
+ # via gradio
159
+ packaging==25.0
160
+ # via
161
+ # accelerate
162
+ # gradio
163
+ # gradio-client
164
+ # huggingface-hub
165
+ # lazy-loader
166
+ # pooch
167
+ # spaces
168
+ pandas==2.3.0
169
+ # via gradio
170
+ pillow==11.2.1
171
+ # via
172
+ # gradio
173
+ # torchvision
174
+ platformdirs==4.3.8
175
+ # via pooch
176
+ pooch==1.8.2
177
+ # via librosa
178
+ psutil==5.9.8
179
+ # via
180
+ # accelerate
181
+ # spaces
182
+ pycparser==2.22
183
+ # via cffi
184
+ pydantic==2.11.7
185
+ # via
186
+ # fastapi
187
+ # gradio
188
+ # spaces
189
+ pydantic-core==2.33.2
190
+ # via pydantic
191
+ pydub==0.25.1
192
+ # via gradio
193
+ pygments==2.19.2
194
+ # via rich
195
+ python-dateutil==2.9.0.post0
196
+ # via pandas
197
+ python-multipart==0.0.20
198
+ # via gradio
199
+ pytz==2025.2
200
+ # via pandas
201
+ pyyaml==6.0.2
202
+ # via
203
+ # accelerate
204
+ # gradio
205
+ # huggingface-hub
206
+ requests==2.32.4
207
+ # via
208
+ # huggingface-hub
209
+ # pooch
210
+ # spaces
211
+ rich==14.0.0
212
+ # via typer
213
+ ruff==0.12.0
214
+ # via gradio
215
+ safehttpx==0.1.6
216
+ # via gradio
217
+ safetensors==0.5.3
218
+ # via accelerate
219
+ scikit-learn==1.7.0
220
+ # via librosa
221
+ scipy==1.15.3
222
+ # via
223
+ # librosa
224
+ # scikit-learn
225
+ semantic-version==2.10.0
226
+ # via gradio
227
+ shellingham==1.5.4
228
+ # via typer
229
+ six==1.17.0
230
+ # via python-dateutil
231
+ sniffio==1.3.1
232
+ # via anyio
233
+ soundfile==0.13.1
234
+ # via librosa
235
+ soxr==0.5.0.post1
236
+ # via librosa
237
+ spaces==0.37.1
238
+ # via gemma-3n-e4b-it (pyproject.toml)
239
+ starlette==0.46.2
240
+ # via
241
+ # fastapi
242
+ # gradio
243
+ sympy==1.13.1
244
+ # via torch
245
+ threadpoolctl==3.6.0
246
+ # via scikit-learn
247
+ tomlkit==0.13.3
248
+ # via gradio
249
+ torch==2.5.1
250
+ # via
251
+ # gemma-3n-e4b-it (pyproject.toml)
252
+ # accelerate
253
+ # torchvision
254
+ torchvision==0.20.1
255
+ # via gemma-3n-e4b-it (pyproject.toml)
256
+ tqdm==4.67.1
257
+ # via huggingface-hub
258
+ triton==3.1.0
259
+ # via torch
260
+ typer==0.16.0
261
+ # via gradio
262
+ typing-extensions==4.14.0
263
+ # via
264
+ # anyio
265
+ # exceptiongroup
266
+ # fastapi
267
+ # gradio
268
+ # gradio-client
269
+ # huggingface-hub
270
+ # librosa
271
+ # pydantic
272
+ # pydantic-core
273
+ # rich
274
+ # spaces
275
+ # torch
276
+ # typer
277
+ # typing-inspection
278
+ # uvicorn
279
+ typing-inspection==0.4.1
280
+ # via pydantic
281
+ tzdata==2025.2
282
+ # via pandas
283
+ urllib3==2.5.0
284
+ # via requests
285
+ uvicorn==0.34.3
286
+ # via gradio
287
+ websockets==15.0.1
288
+ # via gradio-client
style.css ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ h1 {
2
+ text-align: center;
3
+ display: block;
4
+ }
uv.lock ADDED
The diff for this file is too large to render. See raw diff
 
wheels/timm-1.0.16.dev0-py3-none-any.whl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bc9686fd88dfc74611ac0eb9c6a8598ea33f9cfc8cb1a7477cd9c765c659bae9
3
+ size 2485728
wheels/transformers-4.53.0.dev0-py3-none-any.whl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6f2c9040adc3ac4574b20aaf04883ba8a5f0ef6fc62b1d1ca24744369205fdd5
3
+ size 11532544