Linaqruf commited on
Commit
4568128
Β·
verified Β·
1 Parent(s): c4bb6f8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +351 -352
app.py CHANGED
@@ -1,352 +1,351 @@
1
- """
2
- HuggingFace to ModelScope Migration Tool
3
-
4
- This Gradio app enables migration of models and datasets from HuggingFace to ModelScope.
5
- """
6
-
7
- import os
8
- import shutil
9
- import tempfile
10
- from pathlib import Path
11
- from typing import Tuple, Optional
12
-
13
- import gradio as gr
14
- from huggingface_hub import snapshot_download, HfApi
15
- from modelscope.hub.api import HubApi
16
- from modelscope.hub.constants import Licenses, ModelVisibility
17
-
18
-
19
- class MigrationTool:
20
- """Handles migration of models and datasets between HuggingFace and ModelScope."""
21
-
22
- def __init__(self):
23
- self.hf_api = None
24
- self.ms_api = None
25
- self.temp_dir = None
26
-
27
- def authenticate_hf(self, token: str) -> Tuple[bool, str]:
28
- """Authenticate with HuggingFace."""
29
- try:
30
- self.hf_api = HfApi(token=token)
31
- # Test the token
32
- self.hf_api.whoami(token=token)
33
- return True, "βœ“ HuggingFace authentication successful"
34
- except Exception as e:
35
- return False, f"βœ— HuggingFace authentication failed: {str(e)}"
36
-
37
- def authenticate_ms(self, token: str) -> Tuple[bool, str]:
38
- """Authenticate with ModelScope."""
39
- try:
40
- self.ms_api = HubApi()
41
- self.ms_api.login(token)
42
- return True, "βœ“ ModelScope authentication successful"
43
- except Exception as e:
44
- return False, f"βœ— ModelScope authentication failed: {str(e)}"
45
-
46
- def download_from_hf(
47
- self,
48
- repo_id: str,
49
- repo_type: str = "model"
50
- ) -> Tuple[bool, str, Optional[str]]:
51
- """Download a repository from HuggingFace.
52
-
53
- Args:
54
- repo_id: HuggingFace repository ID (e.g., 'username/repo-name')
55
- repo_type: Type of repository ('model' or 'dataset')
56
-
57
- Returns:
58
- Tuple of (success, message, local_path)
59
- """
60
- try:
61
- # Create temporary directory
62
- self.temp_dir = tempfile.mkdtemp(prefix="hf2ms_")
63
-
64
- # Download the repository
65
- local_path = snapshot_download(
66
- repo_id=repo_id,
67
- repo_type=repo_type,
68
- local_dir=self.temp_dir,
69
- local_dir_use_symlinks=False,
70
- token=self.hf_api.token if self.hf_api else None
71
- )
72
-
73
- return True, f"βœ“ Successfully downloaded {repo_type} from HuggingFace", local_path
74
- except Exception as e:
75
- return False, f"βœ— Download failed: {str(e)}", None
76
-
77
- def upload_to_ms(
78
- self,
79
- local_path: str,
80
- repo_id: str,
81
- repo_type: str = "model",
82
- visibility: str = "public",
83
- license_type: str = "apache-2.0",
84
- chinese_name: Optional[str] = None
85
- ) -> Tuple[bool, str]:
86
- """Upload a repository to ModelScope.
87
-
88
- Args:
89
- local_path: Local path to the repository
90
- repo_id: ModelScope repository ID (e.g., 'username/repo-name')
91
- repo_type: Type of repository ('model' or 'dataset')
92
- visibility: Repository visibility ('public' or 'private')
93
- license_type: License type
94
- chinese_name: Optional Chinese name for the repository
95
-
96
- Returns:
97
- Tuple of (success, message)
98
- """
99
- try:
100
- if not self.ms_api:
101
- return False, "βœ— ModelScope not authenticated"
102
-
103
- # Determine visibility
104
- vis = ModelVisibility.PUBLIC if visibility == "public" else ModelVisibility.PRIVATE
105
-
106
- # Map license types
107
- license_map = {
108
- "apache-2.0": Licenses.APACHE_V2,
109
- "mit": Licenses.MIT,
110
- "gpl-3.0": Licenses.GPL_V3,
111
- "other": Licenses.OTHER,
112
- }
113
- lic = license_map.get(license_type.lower(), Licenses.APACHE_V2)
114
-
115
- # Create repository if it doesn't exist
116
- try:
117
- if repo_type == "model":
118
- self.ms_api.create_model(
119
- model_id=repo_id,
120
- visibility=vis,
121
- license=lic,
122
- chinese_name=chinese_name
123
- )
124
- except Exception as create_error:
125
- # Repository might already exist, continue to push
126
- pass
127
-
128
- # Push the model/dataset
129
- if repo_type == "model":
130
- self.ms_api.push_model(
131
- model_id=repo_id,
132
- model_dir=local_path
133
- )
134
- else:
135
- # For datasets, use similar approach
136
- self.ms_api.push_model(
137
- model_id=repo_id,
138
- model_dir=local_path
139
- )
140
-
141
- return True, f"βœ“ Successfully uploaded {repo_type} to ModelScope"
142
- except Exception as e:
143
- return False, f"βœ— Upload failed: {str(e)}"
144
-
145
- def cleanup(self):
146
- """Clean up temporary files."""
147
- if self.temp_dir and os.path.exists(self.temp_dir):
148
- try:
149
- shutil.rmtree(self.temp_dir)
150
- self.temp_dir = None
151
- except Exception as e:
152
- print(f"Warning: Failed to clean up temporary directory: {e}")
153
-
154
- def migrate(
155
- self,
156
- hf_token: str,
157
- ms_token: str,
158
- hf_repo_id: str,
159
- ms_repo_id: str,
160
- repo_type: str,
161
- visibility: str,
162
- license_type: str,
163
- chinese_name: Optional[str] = None
164
- ) -> str:
165
- """Perform the complete migration process.
166
-
167
- Returns:
168
- Status message with migration progress
169
- """
170
- output = []
171
-
172
- # Validate inputs
173
- if not hf_token or not ms_token:
174
- return "βœ— Error: Both HuggingFace and ModelScope tokens are required"
175
-
176
- if not hf_repo_id or not ms_repo_id:
177
- return "βœ— Error: Both source and destination repository IDs are required"
178
-
179
- # Authenticate with HuggingFace
180
- output.append("πŸ” Authenticating with HuggingFace...")
181
- success, msg = self.authenticate_hf(hf_token)
182
- output.append(msg)
183
- if not success:
184
- return "\n".join(output)
185
-
186
- # Authenticate with ModelScope
187
- output.append("\nπŸ” Authenticating with ModelScope...")
188
- success, msg = self.authenticate_ms(ms_token)
189
- output.append(msg)
190
- if not success:
191
- return "\n".join(output)
192
-
193
- # Download from HuggingFace
194
- output.append(f"\n⬇️ Downloading {repo_type} from HuggingFace: {hf_repo_id}...")
195
- success, msg, local_path = self.download_from_hf(hf_repo_id, repo_type)
196
- output.append(msg)
197
- if not success:
198
- self.cleanup()
199
- return "\n".join(output)
200
-
201
- # Upload to ModelScope
202
- output.append(f"\n⬆️ Uploading {repo_type} to ModelScope: {ms_repo_id}...")
203
- success, msg = self.upload_to_ms(
204
- local_path,
205
- ms_repo_id,
206
- repo_type,
207
- visibility,
208
- license_type,
209
- chinese_name
210
- )
211
- output.append(msg)
212
-
213
- # Cleanup
214
- output.append("\n🧹 Cleaning up temporary files...")
215
- self.cleanup()
216
- output.append("βœ“ Cleanup complete")
217
-
218
- if success:
219
- output.append(f"\nβœ… Migration completed successfully!")
220
- output.append(f"Your {repo_type} is now available at: https://www.modelscope.cn/models/{ms_repo_id}")
221
- else:
222
- output.append(f"\n❌ Migration failed")
223
-
224
- return "\n".join(output)
225
-
226
-
227
- def create_interface():
228
- """Create the Gradio interface."""
229
-
230
- migration_tool = MigrationTool()
231
-
232
- with gr.Blocks(title="HuggingFace to ModelScope Migration Tool") as app:
233
- gr.Markdown("""
234
- # πŸš€ HuggingFace to ModelScope Migration Tool
235
-
236
- Easily migrate your models and datasets from HuggingFace to ModelScope.
237
-
238
- ## πŸ“‹ Instructions:
239
- 1. Get your **HuggingFace token** from: https://huggingface.co/settings/tokens
240
- 2. Get your **ModelScope token** from: https://www.modelscope.cn/my/myaccesstoken
241
- 3. Fill in the repository details below
242
- 4. Click "Start Migration"
243
- """)
244
-
245
- with gr.Row():
246
- with gr.Column():
247
- gr.Markdown("### πŸ”‘ Authentication")
248
- hf_token = gr.Textbox(
249
- label="HuggingFace Token",
250
- type="password",
251
- placeholder="hf_...",
252
- info="Your HuggingFace access token"
253
- )
254
- ms_token = gr.Textbox(
255
- label="ModelScope Token",
256
- type="password",
257
- placeholder="Enter your ModelScope token",
258
- info="Your ModelScope SDK token"
259
- )
260
-
261
- with gr.Column():
262
- gr.Markdown("### πŸ“¦ Repository Details")
263
- repo_type = gr.Radio(
264
- choices=["model", "dataset"],
265
- label="Repository Type",
266
- value="model",
267
- info="Select what you want to migrate"
268
- )
269
- visibility = gr.Radio(
270
- choices=["public", "private"],
271
- label="Visibility",
272
- value="public",
273
- info="Visibility of the repository on ModelScope"
274
- )
275
-
276
- with gr.Row():
277
- with gr.Column():
278
- hf_repo_id = gr.Textbox(
279
- label="Source HuggingFace Repo ID",
280
- placeholder="username/repo-name",
281
- info="e.g., bert-base-uncased or username/my-model"
282
- )
283
-
284
- with gr.Column():
285
- ms_repo_id = gr.Textbox(
286
- label="Destination ModelScope Repo ID",
287
- placeholder="username/repo-name",
288
- info="Your ModelScope username/repo-name"
289
- )
290
-
291
- with gr.Row():
292
- with gr.Column():
293
- license_type = gr.Dropdown(
294
- choices=["apache-2.0", "mit", "gpl-3.0", "other"],
295
- label="License",
296
- value="apache-2.0",
297
- info="License for the repository"
298
- )
299
-
300
- with gr.Column():
301
- chinese_name = gr.Textbox(
302
- label="Chinese Name (Optional)",
303
- placeholder="ζ¨‘εž‹δΈ­ζ–‡εη§°",
304
- info="Optional Chinese name for the repository"
305
- )
306
-
307
- migrate_btn = gr.Button("πŸš€ Start Migration", variant="primary", size="lg")
308
-
309
- output = gr.Textbox(
310
- label="Migration Status",
311
- lines=15,
312
- max_lines=20,
313
- interactive=False,
314
- show_copy_button=True
315
- )
316
-
317
- migrate_btn.click(
318
- fn=migration_tool.migrate,
319
- inputs=[
320
- hf_token,
321
- ms_token,
322
- hf_repo_id,
323
- ms_repo_id,
324
- repo_type,
325
- visibility,
326
- license_type,
327
- chinese_name
328
- ],
329
- outputs=output
330
- )
331
-
332
- gr.Markdown("""
333
- ---
334
- ### πŸ“ Notes:
335
- - Large models may take some time to download and upload
336
- - Make sure you have enough disk space for temporary storage
337
- - Private repositories require appropriate token permissions
338
- - The tool will create the repository on ModelScope if it doesn't exist
339
-
340
- ### πŸ”— Resources:
341
- - [HuggingFace Hub](https://huggingface.co/)
342
- - [ModelScope](https://www.modelscope.cn/)
343
- - [HuggingFace Token Settings](https://huggingface.co/settings/tokens)
344
- - [ModelScope Token Settings](https://www.modelscope.cn/my/myaccesstoken)
345
- """)
346
-
347
- return app
348
-
349
-
350
- if __name__ == "__main__":
351
- app = create_interface()
352
- app.launch(share=False)
 
1
+ """
2
+ HuggingFace to ModelScope Migration Tool
3
+
4
+ This Gradio app enables migration of models and datasets from HuggingFace to ModelScope.
5
+ """
6
+
7
+ import os
8
+ import shutil
9
+ import tempfile
10
+ from pathlib import Path
11
+ from typing import Tuple, Optional
12
+
13
+ import gradio as gr
14
+ from huggingface_hub import snapshot_download, HfApi
15
+ from modelscope.hub.api import HubApi
16
+ from modelscope.hub.constants import Licenses, ModelVisibility
17
+
18
+
19
+ class MigrationTool:
20
+ """Handles migration of models and datasets between HuggingFace and ModelScope."""
21
+
22
+ def __init__(self):
23
+ self.hf_api = None
24
+ self.ms_api = None
25
+ self.temp_dir = None
26
+
27
+ def authenticate_hf(self, token: str) -> Tuple[bool, str]:
28
+ """Authenticate with HuggingFace."""
29
+ try:
30
+ self.hf_api = HfApi(token=token)
31
+ # Test the token
32
+ self.hf_api.whoami(token=token)
33
+ return True, "βœ“ HuggingFace authentication successful"
34
+ except Exception as e:
35
+ return False, f"βœ— HuggingFace authentication failed: {str(e)}"
36
+
37
+ def authenticate_ms(self, token: str) -> Tuple[bool, str]:
38
+ """Authenticate with ModelScope."""
39
+ try:
40
+ self.ms_api = HubApi()
41
+ self.ms_api.login(token)
42
+ return True, "βœ“ ModelScope authentication successful"
43
+ except Exception as e:
44
+ return False, f"βœ— ModelScope authentication failed: {str(e)}"
45
+
46
+ def download_from_hf(
47
+ self,
48
+ repo_id: str,
49
+ repo_type: str = "model"
50
+ ) -> Tuple[bool, str, Optional[str]]:
51
+ """Download a repository from HuggingFace.
52
+
53
+ Args:
54
+ repo_id: HuggingFace repository ID (e.g., 'username/repo-name')
55
+ repo_type: Type of repository ('model' or 'dataset')
56
+
57
+ Returns:
58
+ Tuple of (success, message, local_path)
59
+ """
60
+ try:
61
+ # Create temporary directory
62
+ self.temp_dir = tempfile.mkdtemp(prefix="hf2ms_")
63
+
64
+ # Download the repository
65
+ local_path = snapshot_download(
66
+ repo_id=repo_id,
67
+ repo_type=repo_type,
68
+ local_dir=self.temp_dir,
69
+ local_dir_use_symlinks=False,
70
+ token=self.hf_api.token if self.hf_api else None
71
+ )
72
+
73
+ return True, f"βœ“ Successfully downloaded {repo_type} from HuggingFace", local_path
74
+ except Exception as e:
75
+ return False, f"βœ— Download failed: {str(e)}", None
76
+
77
+ def upload_to_ms(
78
+ self,
79
+ local_path: str,
80
+ repo_id: str,
81
+ repo_type: str = "model",
82
+ visibility: str = "public",
83
+ license_type: str = "apache-2.0",
84
+ chinese_name: Optional[str] = None
85
+ ) -> Tuple[bool, str]:
86
+ """Upload a repository to ModelScope.
87
+
88
+ Args:
89
+ local_path: Local path to the repository
90
+ repo_id: ModelScope repository ID (e.g., 'username/repo-name')
91
+ repo_type: Type of repository ('model' or 'dataset')
92
+ visibility: Repository visibility ('public' or 'private')
93
+ license_type: License type
94
+ chinese_name: Optional Chinese name for the repository
95
+
96
+ Returns:
97
+ Tuple of (success, message)
98
+ """
99
+ try:
100
+ if not self.ms_api:
101
+ return False, "βœ— ModelScope not authenticated"
102
+
103
+ # Determine visibility
104
+ vis = ModelVisibility.PUBLIC if visibility == "public" else ModelVisibility.PRIVATE
105
+
106
+ # Map license types
107
+ license_map = {
108
+ "apache-2.0": Licenses.APACHE_V2,
109
+ "mit": Licenses.MIT,
110
+ "gpl-3.0": Licenses.GPL_V3,
111
+ "other": Licenses.OTHER,
112
+ }
113
+ lic = license_map.get(license_type.lower(), Licenses.APACHE_V2)
114
+
115
+ # Create repository if it doesn't exist
116
+ try:
117
+ if repo_type == "model":
118
+ self.ms_api.create_model(
119
+ model_id=repo_id,
120
+ visibility=vis,
121
+ license=lic,
122
+ chinese_name=chinese_name
123
+ )
124
+ except Exception as create_error:
125
+ # Repository might already exist, continue to push
126
+ pass
127
+
128
+ # Push the model/dataset
129
+ if repo_type == "model":
130
+ self.ms_api.push_model(
131
+ model_id=repo_id,
132
+ model_dir=local_path
133
+ )
134
+ else:
135
+ # For datasets, use similar approach
136
+ self.ms_api.push_model(
137
+ model_id=repo_id,
138
+ model_dir=local_path
139
+ )
140
+
141
+ return True, f"βœ“ Successfully uploaded {repo_type} to ModelScope"
142
+ except Exception as e:
143
+ return False, f"βœ— Upload failed: {str(e)}"
144
+
145
+ def cleanup(self):
146
+ """Clean up temporary files."""
147
+ if self.temp_dir and os.path.exists(self.temp_dir):
148
+ try:
149
+ shutil.rmtree(self.temp_dir)
150
+ self.temp_dir = None
151
+ except Exception as e:
152
+ print(f"Warning: Failed to clean up temporary directory: {e}")
153
+
154
+ def migrate(
155
+ self,
156
+ hf_token: str,
157
+ ms_token: str,
158
+ hf_repo_id: str,
159
+ ms_repo_id: str,
160
+ repo_type: str,
161
+ visibility: str,
162
+ license_type: str,
163
+ chinese_name: Optional[str] = None
164
+ ) -> str:
165
+ """Perform the complete migration process.
166
+
167
+ Returns:
168
+ Status message with migration progress
169
+ """
170
+ output = []
171
+
172
+ # Validate inputs
173
+ if not hf_token or not ms_token:
174
+ return "βœ— Error: Both HuggingFace and ModelScope tokens are required"
175
+
176
+ if not hf_repo_id or not ms_repo_id:
177
+ return "βœ— Error: Both source and destination repository IDs are required"
178
+
179
+ # Authenticate with HuggingFace
180
+ output.append("πŸ” Authenticating with HuggingFace...")
181
+ success, msg = self.authenticate_hf(hf_token)
182
+ output.append(msg)
183
+ if not success:
184
+ return "\n".join(output)
185
+
186
+ # Authenticate with ModelScope
187
+ output.append("\nπŸ” Authenticating with ModelScope...")
188
+ success, msg = self.authenticate_ms(ms_token)
189
+ output.append(msg)
190
+ if not success:
191
+ return "\n".join(output)
192
+
193
+ # Download from HuggingFace
194
+ output.append(f"\n⬇️ Downloading {repo_type} from HuggingFace: {hf_repo_id}...")
195
+ success, msg, local_path = self.download_from_hf(hf_repo_id, repo_type)
196
+ output.append(msg)
197
+ if not success:
198
+ self.cleanup()
199
+ return "\n".join(output)
200
+
201
+ # Upload to ModelScope
202
+ output.append(f"\n⬆️ Uploading {repo_type} to ModelScope: {ms_repo_id}...")
203
+ success, msg = self.upload_to_ms(
204
+ local_path,
205
+ ms_repo_id,
206
+ repo_type,
207
+ visibility,
208
+ license_type,
209
+ chinese_name
210
+ )
211
+ output.append(msg)
212
+
213
+ # Cleanup
214
+ output.append("\n🧹 Cleaning up temporary files...")
215
+ self.cleanup()
216
+ output.append("βœ“ Cleanup complete")
217
+
218
+ if success:
219
+ output.append(f"\nβœ… Migration completed successfully!")
220
+ output.append(f"Your {repo_type} is now available at: https://www.modelscope.cn/models/{ms_repo_id}")
221
+ else:
222
+ output.append(f"\n❌ Migration failed")
223
+
224
+ return "\n".join(output)
225
+
226
+
227
+ def create_interface():
228
+ """Create the Gradio interface."""
229
+
230
+ migration_tool = MigrationTool()
231
+
232
+ with gr.Blocks(title="HuggingFace to ModelScope Migration Tool") as app:
233
+ gr.Markdown("""
234
+ # πŸš€ HuggingFace to ModelScope Migration Tool
235
+
236
+ Easily migrate your models and datasets from HuggingFace to ModelScope.
237
+
238
+ ## πŸ“‹ Instructions:
239
+ 1. Get your **HuggingFace token** from: https://huggingface.co/settings/tokens
240
+ 2. Get your **ModelScope token** from: https://www.modelscope.cn/my/myaccesstoken
241
+ 3. Fill in the repository details below
242
+ 4. Click "Start Migration"
243
+ """)
244
+
245
+ with gr.Row():
246
+ with gr.Column():
247
+ gr.Markdown("### πŸ”‘ Authentication")
248
+ hf_token = gr.Textbox(
249
+ label="HuggingFace Token",
250
+ type="password",
251
+ placeholder="hf_...",
252
+ info="Your HuggingFace access token"
253
+ )
254
+ ms_token = gr.Textbox(
255
+ label="ModelScope Token",
256
+ type="password",
257
+ placeholder="Enter your ModelScope token",
258
+ info="Your ModelScope SDK token"
259
+ )
260
+
261
+ with gr.Column():
262
+ gr.Markdown("### πŸ“¦ Repository Details")
263
+ repo_type = gr.Radio(
264
+ choices=["model", "dataset"],
265
+ label="Repository Type",
266
+ value="model",
267
+ info="Select what you want to migrate"
268
+ )
269
+ visibility = gr.Radio(
270
+ choices=["public", "private"],
271
+ label="Visibility",
272
+ value="public",
273
+ info="Visibility of the repository on ModelScope"
274
+ )
275
+
276
+ with gr.Row():
277
+ with gr.Column():
278
+ hf_repo_id = gr.Textbox(
279
+ label="Source HuggingFace Repo ID",
280
+ placeholder="username/repo-name",
281
+ info="e.g., bert-base-uncased or username/my-model"
282
+ )
283
+
284
+ with gr.Column():
285
+ ms_repo_id = gr.Textbox(
286
+ label="Destination ModelScope Repo ID",
287
+ placeholder="username/repo-name",
288
+ info="Your ModelScope username/repo-name"
289
+ )
290
+
291
+ with gr.Row():
292
+ with gr.Column():
293
+ license_type = gr.Dropdown(
294
+ choices=["apache-2.0", "mit", "gpl-3.0", "other"],
295
+ label="License",
296
+ value="apache-2.0",
297
+ info="License for the repository"
298
+ )
299
+
300
+ with gr.Column():
301
+ chinese_name = gr.Textbox(
302
+ label="Chinese Name (Optional)",
303
+ placeholder="ζ¨‘εž‹δΈ­ζ–‡εη§°",
304
+ info="Optional Chinese name for the repository"
305
+ )
306
+
307
+ migrate_btn = gr.Button("πŸš€ Start Migration", variant="primary", size="lg")
308
+
309
+ output = gr.Textbox(
310
+ label="Migration Status",
311
+ lines=15,
312
+ max_lines=20,
313
+ interactive=False,
314
+ )
315
+
316
+ migrate_btn.click(
317
+ fn=migration_tool.migrate,
318
+ inputs=[
319
+ hf_token,
320
+ ms_token,
321
+ hf_repo_id,
322
+ ms_repo_id,
323
+ repo_type,
324
+ visibility,
325
+ license_type,
326
+ chinese_name
327
+ ],
328
+ outputs=output
329
+ )
330
+
331
+ gr.Markdown("""
332
+ ---
333
+ ### πŸ“ Notes:
334
+ - Large models may take some time to download and upload
335
+ - Make sure you have enough disk space for temporary storage
336
+ - Private repositories require appropriate token permissions
337
+ - The tool will create the repository on ModelScope if it doesn't exist
338
+
339
+ ### πŸ”— Resources:
340
+ - [HuggingFace Hub](https://huggingface.co/)
341
+ - [ModelScope](https://www.modelscope.cn/)
342
+ - [HuggingFace Token Settings](https://huggingface.co/settings/tokens)
343
+ - [ModelScope Token Settings](https://www.modelscope.cn/my/myaccesstoken)
344
+ """)
345
+
346
+ return app
347
+
348
+
349
+ if __name__ == "__main__":
350
+ app = create_interface()
351
+ app.launch(share=False)