rootlocalghost commited on
Commit
735ea49
Β·
verified Β·
1 Parent(s): 60b0a02

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +28 -25
app.py CHANGED
@@ -2,12 +2,11 @@ import os
2
  import gc
3
  import torch
4
  import shutil
 
5
  import gradio as gr
6
  from huggingface_hub import HfApi, hf_hub_download
7
  from safetensors.torch import load_file, save_file
8
 
9
- TEMP_DIR = "temp_processing_dir"
10
-
11
  def convert_and_upload(token, source_repo, target_repo, precision, target_components):
12
  if not token:
13
  yield "❌ Error: Please provide a valid Hugging Face Write Token."
@@ -45,53 +44,55 @@ def convert_and_upload(token, source_repo, target_repo, precision, target_compon
45
  yield f"❌ Error fetching files: {str(e)}"
46
  return
47
 
48
- os.makedirs(TEMP_DIR, exist_ok=True)
 
 
 
 
49
 
50
  for file in files:
51
- # AUTO-DELETE/SKIP LOGIC: Detect large .safetensors files at the root level (no slashes in path)
52
  is_root_safetensor = "/" not in file and file.endswith(".safetensors")
53
 
54
  if is_root_safetensor:
55
  yield f"πŸ—‘οΈ Auto-skipping massive root model: {file}..."
56
  try:
57
- # If pushing to an existing repo, explicitly delete the large root file if it exists there
58
  api.delete_file(path_in_repo=file, repo_id=target_repo, token=token, commit_message=f"Auto-deleted massive root file {file}")
59
  yield f"βœ… Ensured {file} is removed from target repository."
60
  except Exception:
61
- pass # File doesn't exist in target repo yet, which is fine
62
  continue
63
 
64
  yield f"⏳ Processing {file}..."
65
 
66
  try:
67
- # Download file locally, bypassing symlink cache to save disk space
 
 
68
  local_path = hf_hub_download(
69
  repo_id=source_repo,
70
  filename=file,
71
- local_dir=TEMP_DIR,
72
- local_dir_use_symlinks=False
73
  )
74
 
75
- # Check if this file belongs to one of the user-selected components (e.g., text_encoder, transformer)
76
  in_target_component = any(f"{comp}/" in file for comp in target_components)
77
 
78
- # Intercept and quantize only if it's a safetensors file in a selected folder
79
  if file.endswith(".safetensors") and in_target_component:
80
- yield f"🧠 Quantizing {file} to {precision}..."
81
 
82
  tensors = load_file(local_path)
83
 
84
- # Cast floating point tensors to the selected precision
85
  if target_dtype:
86
  keys = list(tensors.keys())
87
  for k in keys:
88
  if tensors[k].is_floating_point():
89
  tensors[k] = tensors[k].to(target_dtype)
90
 
91
- converted_path = os.path.join(TEMP_DIR, "converted.safetensors")
92
  save_file(tensors, converted_path)
93
 
94
- # Aggressive memory flush to prevent OOM
95
  del tensors
96
  gc.collect()
97
 
@@ -114,19 +115,23 @@ def convert_and_upload(token, source_repo, target_repo, precision, target_compon
114
  commit_message=f"Copy {file} from original repo"
115
  )
116
 
117
- # Cleanup original downloaded file
118
- if os.path.exists(local_path):
119
- os.remove(local_path)
 
 
120
 
121
  gc.collect()
122
 
123
  except Exception as e:
 
124
  yield f"⚠️ Error processing {file}: {str(e)}\nSkipping to next file..."
125
 
126
- if os.path.exists(TEMP_DIR):
127
- shutil.rmtree(TEMP_DIR)
 
128
 
129
- yield f"βœ… All files processed and successfully uploaded to {target_repo}!"
130
 
131
  # Dynamic UI Update for Target Repo Name
132
  def update_target_repo(username, source, precision):
@@ -139,8 +144,8 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
139
  gr.Markdown("# πŸš€ FLUX.2-klein Dedicated Quantizer")
140
  gr.Markdown(
141
  "Convert sharded **FLUX.2-klein** models (4B and 9B) to lower precisions (FP8, FP16, BF16).\n\n"
142
- "**Auto-Delete OOM Protection:** This tool is strictly designed to handle the sharded `transformer` and `text_encoder` folders. "
143
- "It will **automatically ignore and delete** the massive 16GB/7GB `.safetensors` files located at the root of the repository to ensure your 16GB RAM limit is never breached."
144
  )
145
 
146
  with gr.Row():
@@ -154,7 +159,6 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
154
  label="Your Hugging Face Username",
155
  placeholder="e.g., rootlocalghost"
156
  )
157
- # Locked down to only FLUX.2-klein models
158
  source_repo = gr.Dropdown(
159
  choices=[
160
  "black-forest-labs/FLUX.2-klein-9B",
@@ -192,7 +196,6 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
192
  max_lines=25
193
  )
194
 
195
- # Automatically update the target repo name when inputs change
196
  inputs_to_watch = [hf_username, source_repo, precision]
197
  for inp in inputs_to_watch:
198
  inp.change(
 
2
  import gc
3
  import torch
4
  import shutil
5
+ import uuid
6
  import gradio as gr
7
  from huggingface_hub import HfApi, hf_hub_download
8
  from safetensors.torch import load_file, save_file
9
 
 
 
10
  def convert_and_upload(token, source_repo, target_repo, precision, target_components):
11
  if not token:
12
  yield "❌ Error: Please provide a valid Hugging Face Write Token."
 
44
  yield f"❌ Error fetching files: {str(e)}"
45
  return
46
 
47
+ # Create a unique cache directory for this specific run to prevent collisions
48
+ cache_dir = f"./hf_cache_{uuid.uuid4().hex[:8]}"
49
+
50
+ success_count = 0
51
+ error_count = 0
52
 
53
  for file in files:
54
+ # AUTO-DELETE/SKIP LOGIC: Detect large .safetensors files at the root level
55
  is_root_safetensor = "/" not in file and file.endswith(".safetensors")
56
 
57
  if is_root_safetensor:
58
  yield f"πŸ—‘οΈ Auto-skipping massive root model: {file}..."
59
  try:
 
60
  api.delete_file(path_in_repo=file, repo_id=target_repo, token=token, commit_message=f"Auto-deleted massive root file {file}")
61
  yield f"βœ… Ensured {file} is removed from target repository."
62
  except Exception:
63
+ pass
64
  continue
65
 
66
  yield f"⏳ Processing {file}..."
67
 
68
  try:
69
+ os.makedirs(cache_dir, exist_ok=True)
70
+
71
+ # CRITICAL FIX: Added token=token here so gated FLUX models don't block the download
72
  local_path = hf_hub_download(
73
  repo_id=source_repo,
74
  filename=file,
75
+ cache_dir=cache_dir,
76
+ token=token
77
  )
78
 
 
79
  in_target_component = any(f"{comp}/" in file for comp in target_components)
80
 
 
81
  if file.endswith(".safetensors") and in_target_component:
82
+ yield f"🧠 Quantizing {file} to {precision} (This will take a few minutes)..."
83
 
84
  tensors = load_file(local_path)
85
 
 
86
  if target_dtype:
87
  keys = list(tensors.keys())
88
  for k in keys:
89
  if tensors[k].is_floating_point():
90
  tensors[k] = tensors[k].to(target_dtype)
91
 
92
+ converted_path = "converted.safetensors"
93
  save_file(tensors, converted_path)
94
 
95
+ # Aggressive memory flush
96
  del tensors
97
  gc.collect()
98
 
 
115
  commit_message=f"Copy {file} from original repo"
116
  )
117
 
118
+ success_count += 1
119
+
120
+ # EXTREME DISK CLEANUP: Nuke the cache directory after every file to prevent the 50GB Space Crash
121
+ if os.path.exists(cache_dir):
122
+ shutil.rmtree(cache_dir)
123
 
124
  gc.collect()
125
 
126
  except Exception as e:
127
+ error_count += 1
128
  yield f"⚠️ Error processing {file}: {str(e)}\nSkipping to next file..."
129
 
130
+ # Final cleanup sweep
131
+ if os.path.exists(cache_dir):
132
+ shutil.rmtree(cache_dir)
133
 
134
+ yield f"βœ… Finished! Successfully processed {success_count} files. Errors encountered: {error_count}."
135
 
136
  # Dynamic UI Update for Target Repo Name
137
  def update_target_repo(username, source, precision):
 
144
  gr.Markdown("# πŸš€ FLUX.2-klein Dedicated Quantizer")
145
  gr.Markdown(
146
  "Convert sharded **FLUX.2-klein** models (4B and 9B) to lower precisions (FP8, FP16, BF16).\n\n"
147
+ "**Auto-Delete & Disk Protection:** This tool actively purges Hugging Face's download cache after every single shard. "
148
+ "This ensures the 9B model won't crash the free Space by filling up the 50GB hard drive limit."
149
  )
150
 
151
  with gr.Row():
 
159
  label="Your Hugging Face Username",
160
  placeholder="e.g., rootlocalghost"
161
  )
 
162
  source_repo = gr.Dropdown(
163
  choices=[
164
  "black-forest-labs/FLUX.2-klein-9B",
 
196
  max_lines=25
197
  )
198
 
 
199
  inputs_to_watch = [hf_username, source_repo, precision]
200
  for inp in inputs_to_watch:
201
  inp.change(