4949"""
5050
5151import os
52+ import shutil
53+ import subprocess
5254from typing import Annotated , Literal
5355
56+ # Capture uv path before venv modifies PATH (needed for uvx download method)
57+ UV_PATH = shutil .which ("uv" )
58+
5459
5560def init ():
5661 import logging
5762 import warnings
5863
5964 os .environ ["TOKENIZERS_PARALLELISM" ] = "false"
6065 os .environ ["TORCH_LOGS" ] = "-dynamo"
61- os .environ ["LOGURU_LEVEL" ] = "ERROR"
6266
6367 warnings .filterwarnings ("ignore" )
6468 logging .basicConfig (level = logging .ERROR )
6569
6670
6771init ()
72+ print ("Loading dependencies..." )
6873
6974
7075import base64
7176import json
72- import shutil
7377from io import BytesIO
7478from pathlib import Path
7579
@@ -84,6 +88,9 @@ def init():
8488from llmcompressor .modifiers .quantization import QuantizationModifier
8589from llmcompressor .modifiers .smoothquant import SmoothQuantModifier
8690from llmcompressor .utils import dispatch_for_generation
91+ from loguru import logger as loguru_logger
92+
93+ loguru_logger .remove ()
8794from PIL import Image
8895from qwen_vl_utils import process_vision_info
8996from transformers import AutoProcessor , Qwen3VLForConditionalGeneration
@@ -113,6 +120,48 @@ class Args(pydantic.BaseModel):
113120 """Seed to use for random number generator."""
114121
115122
123+ def download_assets (model : str ) -> Path :
124+ """Pre-download dataset and model & returns model path."""
125+ if UV_PATH is None :
126+ raise RuntimeError ("uv not found in PATH - required for downloads" )
127+
128+ print ("Pre-downloading dataset: lmms-lab/flickr30k" )
129+ subprocess .run (
130+ [
131+ UV_PATH ,
132+ "tool" ,
133+ "run" ,
134+ "--from" ,
135+ "huggingface_hub[hf-xfer]" ,
136+ "hf" ,
137+ "download" ,
138+ "lmms-lab/flickr30k" ,
139+ "--repo-type" ,
140+ "dataset" ,
141+ ],
142+ check = True ,
143+ )
144+
145+ if (model_path := Path (model )).exists ():
146+ return model_path
147+
148+ print (f"Pre-downloading model: { model } " )
149+ subprocess .run (
150+ [
151+ UV_PATH ,
152+ "tool" ,
153+ "run" ,
154+ "--from" ,
155+ "huggingface_hub[hf-xfer]" ,
156+ "hf" ,
157+ "download" ,
158+ model ,
159+ ],
160+ check = True ,
161+ )
162+ return Path (snapshot_download (model ))
163+
164+
116165def preprocess_and_tokenize (
117166 example : dict , processor : AutoProcessor , max_sequence_length : int
118167) -> dict :
@@ -244,7 +293,12 @@ def remove_keys(d, keys_to_remove):
244293 json .dump (clean_config , f , indent = 2 )
245294
246295
296+ def ignore_weights (dir : str , files : list [str ]) -> list [str ]:
297+ return [f for f in files if f == "config.json" or "safetensors" in f ]
298+
299+
247300def quantize (args : Args ):
301+ model_source_path = download_assets (args .model )
248302 args .output_dir .mkdir (parents = True , exist_ok = True )
249303
250304 model = Qwen3VLForConditionalGeneration .from_pretrained (
@@ -293,24 +347,9 @@ def quantize(args: Args):
293347 config_path = output_dir / "config.json"
294348 print (f"Postprocessing config file { config_path } ..." )
295349 postprocess_config (config_path )
296- if not (model_path := Path (args .model )).exists ():
297- # path for remote model / HF ID
298- snapshot_download (
299- repo_id = args .model ,
300- ignore_patterns = ["config.json" , "*.safetensors*" ],
301- local_dir = output_dir ,
302- )
303- else :
304- # path for local model directory
305- files_to_copy = [
306- f
307- for f in model_path .glob ("*" )
308- if f .name != "config.json"
309- and "safetensors" not in f .name
310- and not f .is_dir ()
311- ]
312- for file in files_to_copy :
313- shutil .copy (file , output_dir / file .name )
350+ shutil .copytree (
351+ model_source_path , output_dir , ignore = ignore_weights , dirs_exist_ok = True
352+ )
314353 print (f"Quantization complete! Model saved to: { output_dir } " )
315354
316355
0 commit comments