tumuyan2 commited on
Commit
be653aa
·
1 Parent(s): 1d066cb
Files changed (3) hide show
  1. .gitignore +1 -0
  2. app.py +141 -66
  3. requirements.txt +2 -1
.gitignore CHANGED
@@ -3,3 +3,4 @@
3
  *.bin
4
  *.onnx
5
  *.param
 
 
3
  *.bin
4
  *.onnx
5
  *.param
6
+ *.zip
app.py CHANGED
@@ -1,5 +1,6 @@
1
  import gradio as gr
2
  import os
 
3
  import requests
4
  import shutil
5
  import uuid
@@ -23,12 +24,14 @@ def print_log(task_id, filename, stage, status):
23
  print(f"任务{task_id}: {filename}, [{status}] {stage}")
24
 
25
  # 修改 start_process 函数,处理新增输入
26
- def start_process(input1, input2, shape0_str, shape1_str, input_suffix=".pth"):
27
  global task_counter
28
  task_counter += 1
29
  task_id = task_counter
 
30
  print_log(task_id, input2, input1, "input1")
31
  log = "转换过程非常慢,请耐心等待。显示文件列表不代表转换完成。如果未发生错误,转换结束会显示”任务完成“\n"
 
32
  yield [], log
33
  if input2 == None or input2.strip() == "":
34
  split_input = os.path.splitext(os.path.basename(input1))
@@ -115,8 +118,8 @@ def start_process(input1, input2, shape0_str, shape1_str, input_suffix=".pth"):
115
  # 检查文件大小
116
  try:
117
  file_size = os.path.getsize(file_path) / 1024 /1024 # 转换为 KB
118
- if file_size > 100 :
119
- log += f"文件太大,建议 100MB 以内,当前文件大小为 {file_size } MB。\n"
120
  print_log(task_id, input2, "文件太大("+ file_size +"MB)", "失败")
121
  yield [], log
122
  return
@@ -148,7 +151,7 @@ def start_process(input1, input2, shape0_str, shape1_str, input_suffix=".pth"):
148
  # 如果解析过程中出现 ValueError,将 shape0 和 shape1 设置为全 0
149
  shape0 = [0, 0, 0, 0]
150
  shape1 = [0, 0, 0, 0]
151
- log += "输入的 shape 字符串格式不正确,请使用逗号分隔的整数。\n"
152
  yield [], log
153
  return
154
 
@@ -157,15 +160,15 @@ def start_process(input1, input2, shape0_str, shape1_str, input_suffix=".pth"):
157
  print_log(task_id, input2, "生成输入张量", "开始")
158
  log += "生成张量…\n"
159
  yield [], log
160
- pt_path = output_folder + "/" + input2 + ".pt"
161
- # onnx_path = output_folder + "/" + input2 + ".onnx"
162
  input_tensor0 = torch.rand(shape0) if any(shape0) else None
163
  input_tensor1 = torch.rand(shape1) if any(shape1) else None
164
- if input_tensor0 is not None and input_tensor1 is not None:
165
  example_input = (input_tensor0, input_tensor1)
166
  # 修改此处,去除 shape 字符串中的空格
167
  command = f"pnnx {pt_path} inputshape={str(shape0).replace(' ', '')} inputshape2={str(shape1).replace(' ', '')}"
168
- elif input_tensor0 is not None:
169
  example_input = input_tensor0
170
  command = f"pnnx {pt_path} inputshape={str(shape0).replace(' ', '')}"
171
  else:
@@ -219,61 +222,129 @@ def start_process(input1, input2, shape0_str, shape1_str, input_suffix=".pth"):
219
  log+= ("获得缩放倍率="+str(width_ratio)+", 输出shape="+str(list(example_output.shape))+"\n")
220
  yield [], log
221
 
222
- print_log(task_id, input2, "执行命令" + command, "开始")
223
- log += "执行命令…\n"
224
- yield [], log
225
-
226
- try:
227
- # 使用 subprocess.Popen 执行命令
228
- process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
229
- while True:
230
- output = process.stdout.readline()
231
- if output == '' and process.poll() is not None:
232
- break
233
- if output:
234
- #
235
- if log_to_terminal:
236
- print(output.strip())
237
- log += output.strip() + '\n'
238
- yield [], log
239
- returncode = process.poll()
240
- if returncode != 0:
241
- log += f"执行命令失败,返回码: {returncode},命令: {command} \n"
242
- else:
243
- log += f"执行命令成功: {command} \n"
244
- except Exception as e:
245
- log += f"执行命令: {command} 失败,错误信息: {str(e)}\n"
246
-
247
- # 查找 output_folder 目录下以 .ncnn.bin 和 .ncnn.param 结尾的文件
248
- bin_files = [f for f in os.listdir(output_folder) if f.endswith('.ncnn.bin')]
249
- param_files = [f for f in os.listdir(output_folder) if f.endswith('.ncnn.param')]
250
-
251
 
252
- if bin_files and param_files:
253
- param_file = os.path.join(output_folder, param_files[0])
254
- bin_file = os.path.join(output_folder, bin_files[0])
255
- import zipfile
256
- # 压缩包名称
257
- zip_file_name = os.path.join(output_folder, f"models-{input2}.zip")
258
- # 压缩包内文件夹名称
259
- zip_folder_name = f"models-{input2}"
260
- # 重命名后的文件名
261
- scale = int(width_ratio)
262
- new_bin_name = f"x{scale}.bin"
263
- new_param_name = f"x{scale}.param"
264
- # 创建压缩包
265
- with zipfile.ZipFile(zip_file_name, 'w', zipfile.ZIP_DEFLATED) as zipf:
266
- # 写入重命名后的.bin文件
267
- zipf.write(bin_file, os.path.join(zip_folder_name, new_bin_name))
268
- # 写入重命名后的.param文件
269
- zipf.write(param_file, os.path.join(zip_folder_name, new_param_name))
270
- log += f"已创建压缩包: {zip_file_name}\n"
271
- print_log(task_id, input2, "创建压缩包"+zip_file_name, "完成")
272
  yield [], log
273
  else:
274
- log += f"未找到 ncnn 文件\n"
275
- print_log(task_id, input2, "查找 ncnn 文件", "失败")
276
  yield [], log
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
 
278
  output_files = [os.path.join(output_folder, f) for f in os.listdir(output_folder) if os.path.isfile(os.path.join(output_folder, f))]
279
  log += f"任务完成\n"
@@ -296,7 +367,11 @@ with gr.Blocks() as demo:
296
  input1 = gr.Textbox(label="粘贴地址")
297
  # 新增文件上传组件
298
  input1_file = gr.File(label="上传文件", file_types=[".pth", ".safetensors", ".ckpt"])
299
- input2 = gr.Textbox(label="自定义文件名")
 
 
 
 
300
  # 修改为字符串输入控件
301
  shape0_str = gr.Textbox(label="shape0 (逗号分隔的整数)", value="1,3,128,128")
302
  shape1_str = gr.Textbox(label="shape1 (逗号分隔的整数)", value="0,0,0,0")
@@ -312,7 +387,7 @@ with gr.Blocks() as demo:
312
  # 绑定事件,修改输入参数
313
  process = start_button.click(
314
  fn=start_process,
315
- inputs=[input1_file if input1_file.value else input1, input2, shape0_str, shape1_str],
316
  outputs=[output, log_textbox]
317
  )
318
  # 为取消按钮添加点击事件绑定,使用 cancels 属性取消 start_process 任务
@@ -325,14 +400,14 @@ with gr.Blocks() as demo:
325
 
326
  # 添加范例
327
  examples = [
328
- ["https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-general-x4v3.pth", "", "1,3,128,128", "0,0,0,0"],
329
- ["https://github.com/Phhofm/models/releases/download/4xNomos8kSC/4xNomos8kSC.pth", "", "1,3,128,128", "0,0,0,0"],
330
- ["https://github.com/Phhofm/models/releases/download/1xDeJPG/1xDeJPG_SRFormer_light.pth", "", "1,3,128,128", "0,0,0,0"],
331
- ["https://objectstorage.us-phoenix-1.oraclecloud.com/n/ax6ygfvpvzka/b/open-modeldb-files/o/4x-WTP-ColorDS.pth", "", "1,3,128,128", "0,0,0,0"],
332
  ]
333
  gr.Examples(
334
  examples=examples,
335
- inputs=[input1, input2, shape0_str, shape1_str],
336
  outputs=[output, log_textbox],
337
  fn=start_process
338
  )
 
1
  import gradio as gr
2
  import os
3
+ from gradio.themes import default
4
  import requests
5
  import shutil
6
  import uuid
 
24
  print(f"任务{task_id}: {filename}, [{status}] {stage}")
25
 
26
  # 修改 start_process 函数,处理新增输入
27
+ def start_process(input_file, input_url, input2, shape0_str, shape1_str, output_type="+ Dynamic MNN & NCNN", input_suffix=".pth"):
28
  global task_counter
29
  task_counter += 1
30
  task_id = task_counter
31
+ input1 = input_file if input_file else input_url
32
  print_log(task_id, input2, input1, "input1")
33
  log = "转换过程非常慢,请耐心等待。显示文件列表不代表转换完成。如果未发生错误,转换结束会显示”任务完成“\n"
34
+ output_files = []
35
  yield [], log
36
  if input2 == None or input2.strip() == "":
37
  split_input = os.path.splitext(os.path.basename(input1))
 
118
  # 检查文件大小
119
  try:
120
  file_size = os.path.getsize(file_path) / 1024 /1024 # 转换为 KB
121
+ if file_size > 200 :
122
+ log += f"文件太大,建议 200MB 以内,当前文件大小为 {file_size } MB。\n"
123
  print_log(task_id, input2, "文件太大("+ file_size +"MB)", "失败")
124
  yield [], log
125
  return
 
151
  # 如果解析过程中出现 ValueError,将 shape0 和 shape1 设置为全 0
152
  shape0 = [0, 0, 0, 0]
153
  shape1 = [0, 0, 0, 0]
154
+ log += f"输入的 shape 字符串格式不正确,请使用逗号分隔的整数。shape0_str={shape0_str},shape1_str={shape1_str}\n"
155
  yield [], log
156
  return
157
 
 
160
  print_log(task_id, input2, "生成输入张量", "开始")
161
  log += "生成张量…\n"
162
  yield [], log
163
+ output_base = output_folder + "/" + input2
164
+ pt_path = output_base + ".pt"
165
  input_tensor0 = torch.rand(shape0) if any(shape0) else None
166
  input_tensor1 = torch.rand(shape1) if any(shape1) else None
167
+ if "Fixed" in output_type and input_tensor0 is not None and input_tensor1 is not None:
168
  example_input = (input_tensor0, input_tensor1)
169
  # 修改此处,去除 shape 字符串中的空格
170
  command = f"pnnx {pt_path} inputshape={str(shape0).replace(' ', '')} inputshape2={str(shape1).replace(' ', '')}"
171
+ elif "Fixed" in output_type and input_tensor0 is not None:
172
  example_input = input_tensor0
173
  command = f"pnnx {pt_path} inputshape={str(shape0).replace(' ', '')}"
174
  else:
 
222
  log+= ("获得缩放倍率="+str(width_ratio)+", 输出shape="+str(list(example_output.shape))+"\n")
223
  yield [], log
224
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
 
226
+ # 转换为 ONNX 模型
227
+ if str(width_ratio) in input2:
228
+ onnx_path = output_base + ".onnx"
229
+ else:
230
+ onnx_path = output_base + "-x" + str(width_ratio) + ".onnx"
231
+ if os.path.exists(onnx_path):
232
+ print_log(task_id, input2, "转换为ONNX模型", "跳过")
233
+ log += "跳过转换为ONNX模型\n"
 
 
 
 
 
 
 
 
 
 
 
 
234
  yield [], log
235
  else:
236
+ print_log(task_id, input2, "转换为ONNX模型", "开始")
237
+ log += "转换为ONNX模型…\n"
238
  yield [], log
239
+ torch.onnx.export(torch_model, example_input, onnx_path, opset_version=17, input_names=["input"], output_names=["output"])
240
+
241
+
242
+ # 转换为 mnn 模型
243
+ if "MNN" in output_type:
244
+
245
+ if str(width_ratio) in input2:
246
+ mnn_path = output_base + ".mnn"
247
+ else:
248
+ mnn_path = output_base + "-x" + str(width_ratio) + ".mnn"
249
+
250
+ mnn_config = ""
251
+ if "Fixed" in output_type and input_tensor0 is not None:
252
+ mnn_config = output_base + ".mnnconfig"
253
+ with open(mnn_config, 'w') as f:
254
+ if input_tensor1 is not None:
255
+ f.write(f"input_names = input0, input1\n")
256
+ f.write(f"input_dims = {'x'.join(map(str, shape0))}, {'x'.join(map(str, shape0))},\n")
257
+ else:
258
+ f.write(f"input_names = input\n")
259
+ f.write(f"input_dims = {'x'.join(map(str, shape0))}\n")
260
+
261
+ if os.path.exists(mnn_path):
262
+ print_log(task_id, input2, "转换为MNN模型", "跳过")
263
+ log += "跳过转换为MNN模型\n"
264
+ yield [], log
265
+ else:
266
+ print_log(task_id, input2, "转换为MNN模型", "开始")
267
+ log += "转换为MNN模型…\n"
268
+ mnn_command = f"MNNConvert -f ONNX --modelFile \"{onnx_path}\" --MNNModel \"{mnn_path}\" --bizCode biz --fp16 --info --detectSparseSpeedUp"
269
+ if mnn_config:
270
+ mnn_command += f" --inputConfigFile \"{mnn_config}\""
271
+ try:
272
+ # 使用 subprocess.Popen 执行命令
273
+ process = subprocess.Popen(mnn_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
274
+ while True:
275
+ output = process.stdout.readline()
276
+ if output == '' and process.poll() is not None:
277
+ break
278
+ if output:
279
+ #
280
+ if log_to_terminal:
281
+ print(output.strip())
282
+ log += output.strip() + '\n'
283
+ yield [], log
284
+ returncode = process.poll()
285
+ if returncode != 0:
286
+ log += f"执行mnn命令失败,返回码: {returncode},命令: {mnn_command} \n"
287
+ else:
288
+ log += f"执行命令成功: {mnn_command} \n"
289
+ except Exception as e:
290
+ log += f"执行命令: {mnn_command} 失败,错误信息: {str(e)}\n"
291
+
292
+ if "NCNN" in output_type:
293
+ print_log(task_id, input2, "执行命令" + command, "开始")
294
+ log += "执行命令…\n"
295
+ yield [], log
296
+
297
+ try:
298
+ # 使用 subprocess.Popen 执行命令
299
+ process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
300
+ while True:
301
+ output = process.stdout.readline()
302
+ if output == '' and process.poll() is not None:
303
+ break
304
+ if output:
305
+ #
306
+ if log_to_terminal:
307
+ print(output.strip())
308
+ log += output.strip() + '\n'
309
+ yield [], log
310
+ returncode = process.poll()
311
+ if returncode != 0:
312
+ log += f"执行命令失败,返回码: {returncode},命令: {command} \n"
313
+ else:
314
+ log += f"执行命令成功: {command} \n"
315
+ except Exception as e:
316
+ log += f"执行命令: {command} 失败,错误信息: {str(e)}\n"
317
+
318
+ # 查找 output_folder 目录下以 .ncnn.bin 和 .ncnn.param 结尾的文件
319
+ bin_files = [f for f in os.listdir(output_folder) if f.endswith('.ncnn.bin')]
320
+ param_files = [f for f in os.listdir(output_folder) if f.endswith('.ncnn.param')]
321
+
322
+
323
+ if bin_files and param_files:
324
+ param_file = os.path.join(output_folder, param_files[0])
325
+ bin_file = os.path.join(output_folder, bin_files[0])
326
+ import zipfile
327
+ # 压缩包名称
328
+ zip_file_name = os.path.join(output_folder, f"models-{input2}.zip")
329
+ # 压缩包内文件夹名称
330
+ zip_folder_name = f"models-{input2}"
331
+ # 重命名后的文件名
332
+ scale = int(width_ratio)
333
+ new_bin_name = f"x{scale}.bin"
334
+ new_param_name = f"x{scale}.param"
335
+ # 创建压缩包
336
+ with zipfile.ZipFile(zip_file_name, 'w', zipfile.ZIP_DEFLATED) as zipf:
337
+ # 写入重命名后的.bin文件
338
+ zipf.write(bin_file, os.path.join(zip_folder_name, new_bin_name))
339
+ # 写入重命名后的.param文件
340
+ zipf.write(param_file, os.path.join(zip_folder_name, new_param_name))
341
+ log += f"已创建压缩包: {zip_file_name}\n"
342
+ print_log(task_id, input2, "创建压缩包"+zip_file_name, "完成")
343
+ yield [], log
344
+ else:
345
+ log += f"未找到 ncnn 文件\n"
346
+ print_log(task_id, input2, "查找 ncnn 文件", "失败")
347
+ yield [], log
348
 
349
  output_files = [os.path.join(output_folder, f) for f in os.listdir(output_folder) if os.path.isfile(os.path.join(output_folder, f))]
350
  log += f"任务完成\n"
 
367
  input1 = gr.Textbox(label="粘贴地址")
368
  # 新增文件上传组件
369
  input1_file = gr.File(label="上传文件", file_types=[".pth", ".safetensors", ".ckpt"])
370
+
371
+
372
+ with gr.Row():
373
+ input2 = gr.Textbox(label="自定义文件名")
374
+ output_type = gr.Dropdown(choices=["TorchScript & ONNX", "+ Fixed MNN & NCNN", "+ Dynamic MNN & NCNN", "Fixed NCNN", "Dynamic NCNN", "Fixed MNN", "Dynamic MNN" ], value="+ Dynamic MNN & NCNN", label="模型类型")
375
  # 修改为字符串输入控件
376
  shape0_str = gr.Textbox(label="shape0 (逗号分隔的整数)", value="1,3,128,128")
377
  shape1_str = gr.Textbox(label="shape1 (逗号分隔的整数)", value="0,0,0,0")
 
387
  # 绑定事件,修改输入参数
388
  process = start_button.click(
389
  fn=start_process,
390
+ inputs=[input1_file, input1, input2, output_type, shape0_str, shape1_str,output_type],
391
  outputs=[output, log_textbox]
392
  )
393
  # 为取消按钮添加点击事件绑定,使用 cancels 属性取消 start_process 任务
 
400
 
401
  # 添加范例
402
  examples = [
403
+ ["","https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-general-x4v3.pth", "", "1,3,128,128", "0,0,0,0"],
404
+ ["","https://github.com/Phhofm/models/releases/download/4xNomos8kSC/4xNomos8kSC.pth", "", "1,3,128,128", "0,0,0,0"],
405
+ ["","https://github.com/Phhofm/models/releases/download/1xDeJPG/1xDeJPG_SRFormer_light.pth", "", "1,3,128,128", "0,0,0,0"],
406
+ ["","https://objectstorage.us-phoenix-1.oraclecloud.com/n/ax6ygfvpvzka/b/open-modeldb-files/o/4x-WTP-ColorDS.pth", "", "1,3,128,128", "0,0,0,0"],
407
  ]
408
  gr.Examples(
409
  examples=examples,
410
+ inputs=[input1_file, input1, input2, shape0_str, shape1_str],
411
  outputs=[output, log_textbox],
412
  fn=start_process
413
  )
requirements.txt CHANGED
@@ -1,4 +1,5 @@
1
  spandrel
2
  torch
3
  pnnx
4
- onnx
 
 
1
  spandrel
2
  torch
3
  pnnx
4
+ onnx
5
+ mnn