mstyslavity commited on
Commit
01411dc
·
verified ·
1 Parent(s): ef8273a

Upload 2 files

Browse files
Files changed (2) hide show
  1. README.md +4 -2
  2. app.py +5 -105
README.md CHANGED
@@ -1,3 +1,4 @@
 
1
  title: mergekit-gui
2
  emoji: 🔀
3
  colorFrom: yellow
@@ -7,5 +8,6 @@ sdk_version: 4.44.1
7
  app_file: app.py
8
  pinned: false
9
  license: apache-2.0
10
- -----
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
+ ---
2
  title: mergekit-gui
3
  emoji: 🔀
4
  colorFrom: yellow
 
8
  app_file: app.py
9
  pinned: false
10
  license: apache-2.0
11
+ ---
12
+
13
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py CHANGED
@@ -17,34 +17,12 @@ from clean_community_org import garbage_collect_empty_models
17
  from apscheduler.schedulers.background import BackgroundScheduler
18
  from datetime import timezone
19
 
20
- # HF Spaces: needed for ZeroGPU. Safe on CPU Spaces too.
21
- try:
22
- import spaces # type: ignore
23
- except Exception:
24
- spaces = None
25
- import yaml
26
- from gradio_logsview.logsview import Log, LogsView, LogsViewRunner
27
- from mergekit.config import MergeConfiguration
28
-
29
- from clean_community_org import garbage_collect_empty_models
30
-
31
- def _build_cli(use_cuda: bool) -> str:
32
- """Build mergekit CLI string.
33
-
34
- NOTE: On HF ZeroGPU, torch.cuda.is_available() is only True inside a @spaces.GPU call.
35
- """
36
- base = "mergekit-yaml config.yaml merge --copy-tokenizer --allow-crimes"
37
- if use_cuda:
38
- return base + " --cuda --low-cpu-memory --write-model-card"
39
- return base + " --out-shard-size 5B --lazy-unpickle --trust-remote-code"
40
-
41
-
42
  MARKDOWN_DESCRIPTION = """
43
  # mergekit-gui
44
 
45
  The fastest way to perform a model merge 🔥
46
 
47
- Specify a YAML configuration file (see examples below) and a HF token and this app will perform the merge and upload the merged model to your user profile.
48
  """
49
 
50
  MARKDOWN_ARTICLE = """
@@ -104,86 +82,6 @@ examples = [[str(f)] for f in pathlib.Path("examples").glob("*.yaml")]
104
  COMMUNITY_HF_TOKEN = os.getenv("COMMUNITY_HF_TOKEN")
105
 
106
 
107
- def _merge_impl(yaml_config: str, hf_token: str, repo_name: str, *, force_cuda: bool = False) -> Iterable[List[Log]]:
108
- runner = LogsViewRunner()
109
-
110
- # Decide CUDA at call-time. On ZeroGPU, CUDA is only available inside a @spaces.GPU function.
111
- use_cuda = bool(force_cuda) or torch.cuda.is_available()
112
- cli = _build_cli(use_cuda)
113
-
114
- if not yaml_config:
115
- yield runner.log("Empty yaml, pick an example below", level="ERROR")
116
- return
117
- try:
118
- merge_config = MergeConfiguration.model_validate(yaml.safe_load(yaml_config))
119
- except Exception as e:
120
- yield runner.log(f"Invalid yaml {e}", level="ERROR")
121
- return
122
-
123
- is_community_model = False
124
- if not hf_token:
125
- if "/" in repo_name and not repo_name.startswith("mergekit-community/"):
126
- yield runner.log(
127
- f"Cannot upload merge model to namespace {repo_name.split('/')[0]}: you must provide a valid token.",
128
- level="ERROR",
129
- )
130
- return
131
- yield runner.log(
132
- "No HF token provided. Your merged model will be uploaded to the https://huggingface.co/mergekit-community organization."
133
- )
134
- is_community_model = True
135
- if not COMMUNITY_HF_TOKEN:
136
- raise gr.Error("Cannot upload to community org: community token not set by Space owner.")
137
- hf_token = COMMUNITY_HF_TOKEN
138
-
139
- api = huggingface_hub.HfApi(token=hf_token)
140
-
141
- with tempfile.TemporaryDirectory(ignore_cleanup_errors=True) as tmpdirname:
142
- tmpdir = pathlib.Path(tmpdirname)
143
- merged_path = tmpdir / "merged"
144
- merged_path.mkdir(parents=True, exist_ok=True)
145
- config_path = merged_path / "config.yaml"
146
- config_path.write_text(yaml_config)
147
- yield runner.log(f"Merge configuration saved in {config_path}")
148
-
149
- if not repo_name:
150
- yield runner.log("No repo name provided. Generating a random one.")
151
- repo_name = f"mergekit-{merge_config.merge_method}"
152
- # Make repo_name "unique" (no need to be extra careful on uniqueness)
153
- repo_name += "-" + "".join(random.choices(string.ascii_lowercase, k=7))
154
- repo_name = repo_name.replace("/", "-").strip("-")
155
-
156
- if is_community_model and not repo_name.startswith("mergekit-community/"):
157
- repo_name = f"mergekit-community/{repo_name}"
158
-
159
- try:
160
- yield runner.log(f"Creating repo {repo_name}")
161
- repo_url = api.create_repo(repo_name, exist_ok=True)
162
- yield runner.log(f"Repo created: {repo_url}")
163
- except Exception as e:
164
- yield runner.log(f"Error creating repo {e}", level="ERROR")
165
- return
166
-
167
- # Set tmp HF_HOME to avoid filling up disk Space
168
- tmp_env = os.environ.copy() # taken from https://stackoverflow.com/a/4453495
169
- tmp_env["HF_HOME"] = f"{tmpdirname}/.cache"
170
- full_cli = cli + f" --lora-merge-cache {tmpdirname}/.lora_cache"
171
- yield from runner.run_command(full_cli.split(), cwd=merged_path, env=tmp_env)
172
-
173
- if runner.exit_code != 0:
174
- yield runner.log("Merge failed. Deleting repo as no model is uploaded.", level="ERROR")
175
- api.delete_repo(repo_url.repo_id)
176
- return
177
-
178
- yield runner.log("Model merged successfully. Uploading to HF.")
179
- yield from runner.run_python(
180
- api.upload_folder,
181
- repo_id=repo_url.repo_id,
182
- folder_path=merged_path / "merge",
183
- )
184
- yield runner.log(f"Model successfully uploaded to HF: {repo_url.repo_id}")
185
-
186
-
187
  def run_merge_cpu(runner: LogsViewRunner, cli: str, merged_path: str, tmpdirname: str):
188
  # Set tmp HF_HOME to avoid filling up disk Space
189
  tmp_env = os.environ.copy()
@@ -193,7 +91,7 @@ def run_merge_cpu(runner: LogsViewRunner, cli: str, merged_path: str, tmpdirname
193
  yield ("done", runner.exit_code)
194
 
195
 
196
- @spaces.GPU(duration=60 * 2)
197
  def run_merge_gpu(runner: LogsViewRunner, cli: str, merged_path: str, tmpdirname: str):
198
  yield from run_merge_cpu(
199
  runner,
@@ -341,6 +239,8 @@ def merge(yaml_config: str, hf_token: str, repo_name: str, private: bool) -> Ite
341
  merge.zerogpu = True
342
  run_merge.zerogpu = True
343
 
 
 
344
  def _restart_space():
345
  huggingface_hub.HfApi().restart_space(
346
  repo_id="arcee-ai/mergekit-gui", token=COMMUNITY_HF_TOKEN, factory_reboot=False
@@ -404,4 +304,4 @@ with gr.Blocks() as demo:
404
  button.click(fn=merge, inputs=[config, token, repo_name, private], outputs=[logs])
405
 
406
 
407
- demo.queue(default_concurrency_limit=1).launch()
 
17
  from apscheduler.schedulers.background import BackgroundScheduler
18
  from datetime import timezone
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  MARKDOWN_DESCRIPTION = """
21
  # mergekit-gui
22
 
23
  The fastest way to perform a model merge 🔥
24
 
25
+ Specify a YAML configuration file (see examples below) and a HF token and this app will perform the merge and upload the merged model to your user profile. Uses Zero GPU quota to perform the merge.
26
  """
27
 
28
  MARKDOWN_ARTICLE = """
 
82
  COMMUNITY_HF_TOKEN = os.getenv("COMMUNITY_HF_TOKEN")
83
 
84
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  def run_merge_cpu(runner: LogsViewRunner, cli: str, merged_path: str, tmpdirname: str):
86
  # Set tmp HF_HOME to avoid filling up disk Space
87
  tmp_env = os.environ.copy()
 
91
  yield ("done", runner.exit_code)
92
 
93
 
94
+ @spaces.GPU(duration=60 * 5)
95
  def run_merge_gpu(runner: LogsViewRunner, cli: str, merged_path: str, tmpdirname: str):
96
  yield from run_merge_cpu(
97
  runner,
 
239
  merge.zerogpu = True
240
  run_merge.zerogpu = True
241
 
242
+
243
+ # This is workaround. As the space always getting stuck.
244
  def _restart_space():
245
  huggingface_hub.HfApi().restart_space(
246
  repo_id="arcee-ai/mergekit-gui", token=COMMUNITY_HF_TOKEN, factory_reboot=False
 
304
  button.click(fn=merge, inputs=[config, token, repo_name, private], outputs=[logs])
305
 
306
 
307
+ demo.queue(default_concurrency_limit=1).launch()