|
import argparse |
|
import os |
|
import subprocess |
|
from pathlib import Path |
|
import logging |
|
|
|
|
|
logging.basicConfig( |
|
level=logging.INFO, |
|
style="{", |
|
datefmt="%Y-%m-%d %H:%M:%S", |
|
format="[{asctime}] {levelname} {filename}:{lineno}: {message}", |
|
) |
|
|
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
def main(apk_path: Path, package_output_path: Path): |
|
"""Push weights to the android device with adb""" |
|
|
|
logger.info('Install apk "%s" to device', str(apk_path.absolute())) |
|
subprocess.run(["adb", "install", str(apk_path)], check=True, env=os.environ) |
|
|
|
device_weihgt_dir = "/storage/emulated/0/Android/data/ai.mlc.mlcchat/files/" |
|
logger.info('Creating directory "%s" on device', device_weihgt_dir) |
|
subprocess.run( |
|
["adb", "shell", "mkdir", "-p", device_weihgt_dir], |
|
check=True, |
|
env=os.environ, |
|
) |
|
for model_weight_dir in (package_output_path / "bundle").iterdir(): |
|
if model_weight_dir.is_dir(): |
|
src_path = str(model_weight_dir.absolute()) |
|
dst_path = "/data/local/tmp/" + model_weight_dir.name |
|
logger.info('Pushing local weights "%s" to device location "%s"', src_path, dst_path) |
|
subprocess.run(["adb", "push", src_path, dst_path], check=True, env=os.environ) |
|
|
|
src_path = dst_path |
|
dst_path = "/storage/emulated/0/Android/data/ai.mlc.mlcchat/files/" |
|
logger.info('Move weights from "%s" to "%s"', src_path, dst_path) |
|
subprocess.run(["adb", "shell", "mv", src_path, dst_path], check=True, env=os.environ) |
|
logger.info("All finished.") |
|
|
|
|
|
if __name__ == "__main__": |
|
parser = argparse.ArgumentParser("MLC LLM Android Weight Bundle") |
|
|
|
def _parse_apk_path(path: str) -> Path: |
|
path = Path(path) |
|
if not path.exists(): |
|
raise ValueError( |
|
f"Path {str(path)} is expected to be an apk file, but the file does not exist." |
|
) |
|
if not path.is_file(): |
|
raise ValueError(f"Path {str(path)} is expected to be an apk file.") |
|
return path |
|
|
|
parser.add_argument( |
|
"--apk-path", |
|
type=_parse_apk_path, |
|
default="app/release/app-release.apk", |
|
help="The path to generated MLCChat apk file.", |
|
) |
|
parser.add_argument( |
|
"--package-output-path", |
|
type=Path, |
|
default="./", |
|
help='The path to the output directory of "mlc_llm package".', |
|
) |
|
args = parser.parse_args() |
|
main(args.apk_path, args.package_output_path) |
|
|