121 lines
4.2 KiB
Python
121 lines
4.2 KiB
Python
import json
|
|
import os
|
|
import shlex
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
def convert(onnx_path, mnn_path, extra):
|
|
print('Onnx path: ', onnx_path)
|
|
print('MNN path: ', mnn_path)
|
|
print('Extra: ', extra)
|
|
convert_path = '../../../build/MNNConvert'
|
|
if not os.path.exists(convert_path):
|
|
print(convert_path + " not exist, use pymnn instead")
|
|
convert_path = 'mnnconvert'
|
|
extra_args = shlex.split(extra) if extra else []
|
|
models = ['text_encoder', 'unet', 'vae_decoder']
|
|
for model in models:
|
|
cmd = [
|
|
convert_path,
|
|
'-f', 'ONNX',
|
|
'--modelFile', os.path.join(onnx_path, model, 'model.onnx'),
|
|
'--MNNModel', os.path.join(mnn_path, model + '.mnn'),
|
|
'--saveExternalData=1',
|
|
] + extra_args
|
|
print(' '.join(shlex.quote(x) for x in cmd))
|
|
result = subprocess.run(cmd, check=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
|
|
print(result.stdout)
|
|
|
|
|
|
def export_diffusion_mtok(tokenizer_src_root, model_root):
|
|
this_dir = Path(__file__).resolve().parent
|
|
llm_export_dir = (this_dir / '../../llm/export').resolve()
|
|
if str(llm_export_dir) not in sys.path:
|
|
sys.path.insert(0, str(llm_export_dir))
|
|
|
|
from transformers import AutoTokenizer
|
|
from utils.tokenizer import LlmTokenizer
|
|
|
|
def read_model_type(dir_path):
|
|
for name in ('config.json', 'tokenizer_config.json'):
|
|
config_path = dir_path / name
|
|
if not config_path.exists():
|
|
continue
|
|
try:
|
|
with config_path.open('r', encoding='utf-8') as fp:
|
|
model_type = json.load(fp).get('model_type')
|
|
if model_type:
|
|
return model_type
|
|
except Exception:
|
|
pass
|
|
return None
|
|
|
|
def load_tokenizer(dir_path, use_fast):
|
|
return AutoTokenizer.from_pretrained(dir_path.as_posix(), trust_remote_code=True, use_fast=use_fast)
|
|
|
|
def infer_model_type(dir_path):
|
|
model_type = read_model_type(dir_path)
|
|
if model_type:
|
|
return model_type
|
|
tokenizer = None
|
|
for use_fast in (False, True):
|
|
try:
|
|
tokenizer = load_tokenizer(dir_path, use_fast=use_fast)
|
|
break
|
|
except Exception:
|
|
pass
|
|
if tokenizer is None:
|
|
return 'clip'
|
|
class_name = type(tokenizer).__name__.lower()
|
|
if 'bert' in class_name:
|
|
return 'bert'
|
|
if 't5' in class_name:
|
|
return 't5'
|
|
return 'clip'
|
|
|
|
src_root = Path(tokenizer_src_root)
|
|
dst_root = Path(model_root)
|
|
|
|
candidate_dirs = []
|
|
if (src_root / 'tokenizer').is_dir():
|
|
candidate_dirs.append((src_root / 'tokenizer', dst_root))
|
|
elif src_root.is_dir():
|
|
candidate_dirs.append((src_root, dst_root))
|
|
|
|
for src_dir, dst_dir in candidate_dirs:
|
|
dst_dir.mkdir(parents=True, exist_ok=True)
|
|
for item in src_dir.iterdir():
|
|
if item.is_file():
|
|
target = dst_dir / item.name
|
|
if target.resolve() != item.resolve():
|
|
target.write_bytes(item.read_bytes())
|
|
|
|
tokenizer_json = dst_dir / 'tokenizer.json'
|
|
if not tokenizer_json.exists():
|
|
hf_tok = None
|
|
for use_fast in (False, True):
|
|
try:
|
|
hf_tok = load_tokenizer(dst_dir, use_fast=use_fast)
|
|
break
|
|
except Exception:
|
|
pass
|
|
if hf_tok is None:
|
|
raise RuntimeError(f'Failed to materialize tokenizer.json from {dst_dir}')
|
|
hf_tok.save_pretrained(dst_dir.as_posix())
|
|
|
|
model_type = infer_model_type(dst_dir)
|
|
llm_tok = LlmTokenizer(dst_dir.as_posix(), model_type)
|
|
out_path = llm_tok.export(dst_dir.as_posix(), model_path=dst_dir.as_posix(), model_type=model_type)
|
|
if out_path.endswith('tokenizer.mtok'):
|
|
print(f'Export tokenizer to {out_path}')
|
|
else:
|
|
print(f'Warning: tokenizer export fallback for {dst_dir}, got {out_path}')
|
|
|
|
if __name__ == '__main__':
|
|
extra = ""
|
|
extra = " ".join(sys.argv[3:])
|
|
convert(sys.argv[1], sys.argv[2], extra)
|
|
export_diffusion_mtok(sys.argv[1], sys.argv[2])
|