
    
iՇ                     2   % S r SSKrSSKrSSKrSSKrSSKrSSKJrJrJ	r	J
r
  SSKJr  SSKJr  SSSSSSSSSSSS	S
SS.r\	\\4   \S'   S\4S jrS\S\4S jrS\S\\   4S jrS\S\\   4S jrSLS\S\4S jjr SMS\S\S\\   SS4S jjrS\S\SS4S jr  SNS\S\S\\   S\\   S\
\\4   4
S jjrSrSS S!S"S#S$S%S&S'S(S).
r\	\\4   \S*'   / S+QrS,rS-S.0r \	\\4   \S/'   S0r!S\4S1 jr"SMS2\\   S\4S3 jjr#S4\S\4S5 jr$SMS6\\   S\4S7 jjr%SMS\S6\\   S\4S8 jjr&S\	\\4   4S9 jr'    SOS6\\   S:\S\\   S\\   S\
\\4   4
S; jjr(    SOS\S6\\   S:\S\\   S\\   S\
\\4   4S< jjr)   SPS6\\   S:\S\\   S\
\\\   4   4S= jjr*   SQS6\\   S\\   S\\   S\
\\4   4S> jjr+    SRS\\   S6\\   S\\   S\\   S\
\\4   4
S? jjr,   SQS\S6\\   S\\   S\\   S\
\\4   4
S@ jjr-S\\   4SA jr.SBSCSD\\   S\4SE jr/SMSD\S6\\   S\4SF jjr0    SOSD\S6\\   S:\S\\   S\\   S\
\\4   4SG jjr1    SRSD\\   S6\\   S\\   S\\   S\
\\4   4
SH jjr2SI r3SJ r4\5SK:X  a  \Rl                  " \4" 5       5        gg)Sz
ACE-Step Model Downloader

This module provides functionality to download models from HuggingFace Hub or ModelScope.
It supports automatic downloading when models are not found locally,
with intelligent fallback between download sources.
    N)OptionalListDictTuple)Path)loggerturbosftbasexl_basexl_sftxl_turbo)acestep-v15-turboacestep-v15-sftacestep-v15-basezacestep-v15-base-sft-fix-instacestep-v15-turbo-shift1acestep-v15-turbo-shift3acestep-v15-turbo-continuousz!acestep-v15-turbo-fix-inst-shift3z+acestep-v15-turbo-fix-inst-shift-continuousz(acestep-v15-turbo-fix-inst-shift-dynamiczacestep-v15-turbo-rlacestep-v15-xl-baseacestep-v15-xl-sftacestep-v15-xl-turbo_CHECKPOINT_TO_VARIANTreturnc                  V    [        [        5      R                  5       R                  S-  $ )zHGet the acestep/models/ directory (authoritative source for model code).models)r   __file__resolveparent     O/mnt/workspace/acestep.cpp/tests/../../ACE-Step-1.5/acestep/model_downloader.py_get_models_source_dirr"   .   s     >!!#**X55r    filepathc                   ^ [         R                  " 5       n[        U S5       m[        U4S jS5       H  nUR	                  U5        M     SSS5        UR                  5       $ ! , (       d  f       UR                  5       $ = f)z*Compute SHA-256 hash of a file's contents.rbc                  &   > T R                  S5      $ )Ni    )read)fs   r!   <lambda>_file_hash.<locals>.<lambda>7   s    !&&,r    r    N)hashlibsha256openiterupdate	hexdigest)r#   hchunkr(   s      @r!   
_file_hashr3   3   sb    A	h	.4EHHUO 5 
 ;;= 
	 ;;=s   )A$$
B
model_namec                    [         R                  U 5      nUc  / $ [        5       U-  nUR                  5       (       d  / $ [	        U[
        5      (       a  [        U5      nX-  n/ nUR                  S5       H  nUR                  S:X  a  M  XFR                  -  nUR                  5       (       d  UR                  UR                  5        MU  [        U5      [        U5      :w  d  Mo  UR                  UR                  5        M     U$ )a?  
Compare .py files in acestep/models/{variant}/ with those in the checkpoint directory.

Args:
    model_name: Checkpoint directory name (e.g. "acestep-v15-turbo")
    checkpoints_dir: Path to the checkpoints root directory

Returns:
    List of filenames that differ (empty list if all match or model_name is unknown)
*.py__init__.py)r   getr"   exists
isinstancestrr   globnameappendr3   )r4   checkpoints_dirvariant
source_dir
target_dir
mismatchedsrc_filedst_files           r!   _check_code_mismatchrF   <   s     %((4G	')G3J	/3''/ -JJOOF+==M)-  hmm,!Z%99hmm, , r    c                 ~   [         R                  U 5      nUc  / $ [        5       U-  nUR                  5       (       d  [        R
                  " SU 35        / $ [        U[        5      (       a  [        U5      nX-  nUR                  5       (       d  [        R
                  " SU 35        / $ / nUR                  S5       Hz  nUR                  S:X  a  M  XFR                  -  n[        R                  " Xg5        UR                  UR                  5        [        R                  " SUR                   SU 35        M|     U$ )af  
Copy .py files from acestep/models/{variant}/ into the checkpoint directory,
overwriting the HuggingFace-downloaded versions.

Args:
    model_name: Checkpoint directory name (e.g. "acestep-v15-turbo")
    checkpoints_dir: Path to the checkpoints root directory

Returns:
    List of filenames that were synced (empty if model_name is unknown or no source)
z)[Model Sync] Source directory not found: z)[Model Sync] Target directory not found: r6   r7   z[Model Sync] Synced  -> )r   r8   r"   r9   r   warningr:   r;   r   r<   r=   shutilcopy2r>   debug)r4   r?   r@   rA   rB   syncedrD   rE   s           r!   _sync_model_code_filesrN   `   s    %((4G	')G3JB:,OP	/3''/ -JB:,OP	FOOF+==M)-X(hmm$+HMM?$xjIJ , Mr    timeoutc                 X   SSK nUR                  UR                  UR                  5      n UR                  U 5        UR	                  S5         UR                  5         g! UR                  UR                  [        4 a     UR                  5         gf = f! UR                  5         f = f)z
Check if Google is accessible (to determine HuggingFace vs ModelScope).

Args:
    timeout: Connection timeout in seconds

Returns:
    True if Google is accessible, False otherwise
r   N)zwww.google.comi  TF)	socketAF_INETSOCK_STREAM
settimeoutconnectcloserO   errorOSError)rO   rQ   socks      r!   _can_access_googlerZ      s     ==););<D ,- 	

 NNFLL'2 

 	

s#   "A   !BB BB B)repo_id	local_dirtokenc                 l    SSK Jn  [        R                  " SU  SU 35        U" U [	        U5      SUS9  g)a  
Internal function to download from HuggingFace Hub.

Args:
    repo_id: HuggingFace repository ID (e.g., "ACE-Step/Ace-Step1.5")
    local_dir: Local directory to save the model
    token: HuggingFace token for private repos (optional)

Raises:
    Exception: If download fails
r   snapshot_downloadz/[Model Download] Downloading from HuggingFace: rH   auto)r[   r\   local_dir_use_symlinksr]   N)huggingface_hubr`   r   infor;   )r[   r\   r]   r`   s       r!   #_download_from_huggingface_internalre      s9      2
KKA'$ykZ[i.%	r    c                 h    SSK Jn  [        R                  " SU  SU 35        U" U [	        U5      S9  g)z
Internal function to download from ModelScope.

Args:
    repo_id: ModelScope repository ID (e.g., "ACE-Step/Ace-Step1.5")
    local_dir: Local directory to save the model

Raises:
    Exception: If download fails
r   r_   z.[Model Download] Downloading from ModelScope: rH   )model_idr\   N)
modelscoper`   r   rd   r;   )r[   r\   r`   s      r!   "_download_from_modelscope_internalri      s3     -
KK@	i[YZi.r    prefer_sourcec                    UR                  SSS9  US:X  a  Sn[        R                  " S5        OMUS:X  a  Sn[        R                  " S5        O.[        5       nUn[        R                  " SU(       a  S	OS
 35        U(       a*  [        R                  " S5         [	        XU5        SSU  34$ [        R                  " S5         [        X5        SSU  34$ ! [
         a  n[        R                  " SU 35        [        R                  " S5         [        X5        SSU  34s SnA$ ! [
         a1  nSU SU 3n[        R                  " U5        SU4s SnAs SnA$ SnAff = fSnAff = f! [
         a  n[        R                  " SU 35        [        R                  " S5         [	        XU5        SSU  34s SnA$ ! [
         a1  nSU SU 3n[        R                  " U5        SU4s SnAs SnA$ SnAff = fSnAff = f)a+  
Smart download with automatic fallback between HuggingFace and ModelScope.

Automatically detects network environment and chooses the best download source.
If the primary source fails, automatically falls back to the alternative.

Args:
    repo_id: Repository ID (same format for both HF and ModelScope)
    local_dir: Local directory to save the model
    token: HuggingFace token for private repos (optional)
    prefer_source: Preferred download source ("huggingface", "modelscope", or None for auto-detect)

Returns:
    Tuple of (success, message)
Tparentsexist_okhuggingfacez1[Model Download] User preference: HuggingFace Hubrh   Fz,[Model Download] User preference: ModelScopez [Model Download] Auto-detected: zHuggingFace Hub
ModelScopez)[Model Download] Using HuggingFace Hub...z*Successfully downloaded from HuggingFace: z.[Model Download] HuggingFace download failed: z.[Model Download] Falling back to ModelScope...z)Successfully downloaded from ModelScope: Nz6Both HuggingFace and ModelScope downloads failed. HF: z, MS: z$[Model Download] Using ModelScope...z-[Model Download] ModelScope download failed: z3[Model Download] Falling back to HuggingFace Hub...z6Both ModelScope and HuggingFace downloads failed. MS: z, HF: )	mkdirr   rd   rZ   re   	ExceptionrI   ri   rW   )	r[   r\   r]   rj   use_huggingface_firstcan_access_googleee2	error_msgs	            r!   _smart_downloadrx      s   , OOD4O0 % $GH	,	& %BC /0 16L]7Hco6pqr?@	(/EJEgYOOO 	:;	(.wBDWINNN  		(NNKA3OPKKHI(27FH	RRR (TUVTWW]^`]ab	Y'i'''(		(  		(NNJ1#NOKKMN(3GNI'SSS (TUVTWW]^`]ab	Y'i'''(		(s   C E. 
E+!/E&D("E+(
E#2!EE#E&E+E##E&&E+.
H8/G>(G :H 
G;
!G6+G;,G>0H6G;;G>>HzACE-Step/Ace-Step1.5zACE-Step/acestep-5Hz-lm-0.6BzACE-Step/acestep-5Hz-lm-4Bz!ACE-Step/acestep-v15-turbo-shift3zACE-Step/acestep-v15-sftzACE-Step/acestep-v15-basez!ACE-Step/acestep-v15-turbo-shift1z%ACE-Step/acestep-v15-turbo-continuouszACE-Step/acestep-v15-xl-basezACE-Step/acestep-v15-xl-sftzACE-Step/acestep-v15-xl-turbo)
zacestep-5Hz-lm-0.6Bzacestep-5Hz-lm-4Br   r   r   r   r   r   r   r   SUBMODEL_REGISTRY)r   vaezQwen3-Embedding-0.6Bacestep-5Hz-lm-1.7Br{   scragvaezscragnog/Ace-Step-1.5-ScragVAEVAE_REGISTRYofficialc                      [         R                  R                  S5      n U (       a  [        U 5      R	                  5       $ [        [         R
                  " 5       5      $ )a  Get the project root directory.

Returns the directory set by the ``ACESTEP_PROJECT_ROOT`` environment
variable when present, otherwise the current working directory.  Using
the working directory (rather than ``__file__``) keeps the checkpoints
folder next to where the user launched the process, regardless of whether
the package was installed via ``pip install .`` or run from source.
ACESTEP_PROJECT_ROOT)osenvironr8   r   r   getcwd)env_roots    r!   get_project_rootr   I  s>     zz~~45HH~%%''		r    
custom_dirc                     U (       a  [        U 5      $ [        R                  R                  S5      nU(       a'  [        U5      R	                  5       R                  5       $ [        5       S-  $ )uh  Get the checkpoints directory path.

Resolution order:
1. *custom_dir* argument (passed programmatically)
2. ``ACESTEP_CHECKPOINTS_DIR`` environment variable – allows users to
   share a single model directory across multiple ACE-Step installations,
   avoiding duplicate downloads that waste disk space.
3. ``<project_root>/checkpoints`` (original default)
ACESTEP_CHECKPOINTS_DIRcheckpoints)r   r   r   r8   
expanduserr   r   )r   env_dirs     r!   get_checkpoints_dirr   X  sR     Jjjnn67GG}'')1133--r    
model_pathc                 ^   ^  SnT R                  5       (       d  g[        U 4S jU 5       5      $ )zReturn whether a model directory contains at least one weights artifact.

Args:
    model_path: Candidate model directory path.

Returns:
    `True` when a known model weights file exists in the directory.
)zmodel.safetensorszmodel.safetensors.index.jsonzpytorch_model.binzpytorch_model.bin.index.jsonz#diffusion_pytorch_model.safetensorsz.diffusion_pytorch_model.safetensors.index.jsonzdiffusion_pytorch_model.binz&diffusion_pytorch_model.bin.index.jsonFc              3   J   >#    U  H  nTU-  R                  5       v   M     g 7fN)r9   ).0filenamer   s     r!   	<genexpr>*_contains_model_weights.<locals>.<genexpr>  s$     Q@PH
X%--//@Ps    #)is_dirany)r   weight_filenamess   ` r!   _contains_model_weightsr   j  s1    	 Q@PQQQr    r?   c                     U c  [        5       n O [        U [        5      (       a  [        U 5      n [         H  nX-  n[        U5      (       a  M    g   g)z
Check if the main model components exist in the checkpoints directory.

Returns:
    True if all main model components contain weights, False otherwise.
FT)r   r:   r;   r   MAIN_MODEL_COMPONENTSr   )r?   	componentcomponent_paths      r!   check_main_model_existsr     sN     -/	OS	)	)/*	(4&~66 + r    c                     U (       d  [         R                  " S5        gUc  [        5       nO [        U[        5      (       a  [        U5      nX-  n[        U5      $ )z
Check if a specific model exists in the checkpoints directory.

Args:
    model_name: Name of the model to check
    checkpoints_dir: Custom checkpoints directory (optional)

Returns:
    True if the model exists, False otherwise.
z;[check_model_exists] Empty model_name; treating as missing.F)r   rI   r   r:   r;   r   r   )r4   r?   r   s      r!   check_model_existsr     sO     TU-/	OS	)	)/ -J":..r    c                  "    S[         0[        En U $ )zo
List all available models for download.

Returns:
    Dictionary mapping local names to HuggingFace repo IDs.
main)MAIN_MODEL_REPOry   )r   s    r!   list_available_modelsr     s     	
F Mr    forcec                    U c  [        5       n O [        U [        5      (       a  [        U 5      n U R	                  SSS9  U(       d  [        U 5      (       a  SSU  34$ [        S[         S35        [        SU  35        [        S5        [        [        XU5      u  pEU(       aI  [         H?  nU[        ;   d  M  [        X`5      nU(       d  M#  [        R                  " SU S	U 35        MA     XE4$ )
a/  
Download the main ACE-Step model from HuggingFace or ModelScope.

The main model includes:
- acestep-v15-turbo (default DiT model)
- vae (audio encoder/decoder)
- Qwen3-Embedding-0.6B (text encoder)
- acestep-5Hz-lm-1.7B (default LM model)

Args:
    checkpoints_dir: Custom checkpoints directory (optional)
    force: Force re-download even if model exists
    token: HuggingFace token for private repos (optional)
    prefer_source: Preferred download source ("huggingface", "modelscope", or None for auto-detect)

Returns:
    Tuple of (success, message)
Trl   zMain model already exists at zDownloading main model from ...Destination: z>This may take a while depending on your internet connection...'[Model Download] Synced code files for : )r   r:   r;   r   rq   r   printr   rx   r   r   rN   r   rd   )r?   r   r]   rj   successmsgr   rM   s           r!   download_main_modelr     s    0 -/	OS	)	)/ $6,_==4_4EFFF	((9
=>	M/*
+,	
JK #?OMZLG.I22/	K6KK"I)TVW]V^ _`	 /
 <r    c                 2   U [         ;  a-  SR                  [         R                  5       5      nSSU  SU 34$ Uc  [        5       nO [	        U[
        5      (       a  [        U5      nUR                  SSS9  X-  nU(       d  UR                  5       (       a
  SSU  SU 34$ [         U    n[        S	U  S
U S35        [        SU 35        [        XvX45      u  pU(       a8  U [        ;   a.  [        X5      n
U
(       a  [        R                  " SU  SU
 35        X4$ )a  
Download a specific sub-model from HuggingFace or ModelScope.

Args:
    model_name: Name of the model to download (must be in SUBMODEL_REGISTRY)
    checkpoints_dir: Custom checkpoints directory (optional)
    force: Force re-download even if model exists
    token: HuggingFace token for private repos (optional)
    prefer_source: Preferred download source ("huggingface", "modelscope", or None for auto-detect)

Returns:
    Tuple of (success, message)
, FzUnknown model 'z'. Available models: Trl   zModel '' already exists at zDownloading z from r   r   r   r   )ry   joinkeysr   r:   r;   r   rq   r9   r   rx   r   rN   r   rd   )r4   r?   r   r]   rj   	availabler   r[   r   r   rM   s              r!   download_submodelr     s%   ( **II/4467	
|3HTTT-/	OS	)	)/ $6 -JZ&&((wzl*>zlKKK
+G	LF7)3
78	M*
&' #7MLG:!77'
DKKA*RPVxXY<r    c                 *   U c  [        5       n O [        U [        5      (       a  [        U 5      n / nSn[	        XU5      u  pVUR                  U5        U(       d  Sn[         H-  n[        XpX5      u  pVUR                  U5        U(       a  M+  SnM/     XC4$ )a  
Download all available models.

Args:
    checkpoints_dir: Custom checkpoints directory (optional)
    force: Force re-download even if models exist
    token: HuggingFace token for private repos (optional)

Returns:
    Tuple of (all_success, list of messages)
TF)r   r:   r;   r   r   r>   ry   r   )r?   r   r]   messagesall_successr   r   r4   s           r!   download_all_modelsr   !  s      -/	OS	)	)/HK 'uELGOOC (
(eSwK	 (   r    c                     U c
  [        5       n [        U 5      (       a  g[        S5        [        S5        [        S5        [        XUS9$ )a  
Ensure the main model is available, downloading if necessary.

This function is designed to be called during initialization.
It will only download if the model doesn't exist.

Args:
    checkpoints_dir: Custom checkpoints directory (optional)
    token: HuggingFace token for private repos (optional)
    prefer_source: Preferred download source ("huggingface", "modelscope", or None for auto-detect)

Returns:
    Tuple of (success, message)
)TzMain model is available=
============================================================z4Main model not found. Starting automatic download...=============================================================
r]   rj   )r   r   r   r   )r?   r]   rj   s      r!   ensure_main_modelr   I  sF    & -///.	/	
@A	/=YYr    c                    U c  [         n Uc  [        5       nO [        U[        5      (       a  [	        U5      n[        X5      (       a  SSU  S34$ U [        ;  aP  [         H?  nSUR                  5       ;   d  M  U R                  5       UR                  5       ;   d  M=  Un   O	   SSU  34$ [        S5        [        SU  S35        [        S	5        [        XX#S
9$ )a  
Ensure an LM model is available, downloading if necessary.

Args:
    model_name: Name of the LM model (defaults to DEFAULT_LM_MODEL)
    checkpoints_dir: Custom checkpoints directory (optional)
    token: HuggingFace token for private repos (optional)
    prefer_source: Preferred download source ("huggingface", "modelscope", or None for auto-detect)

Returns:
    Tuple of (success, message)
Tz
LM model '' is availablelmFzUnknown LM model: r   +' not found. Starting automatic download...r   r   )
DEFAULT_LM_MODELr   r:   r;   r   r   ry   lowerr   r   )r4   r?   r]   rj   known_models        r!   ensure_lm_modelr   i  s    $ %
-/	OS	)	)/*66z*^<<< **,K{((**z/?/?/A[EVEVEX/X(
 -
 .zl;;;	/	Jzl"M
NO	/Zccr    c                 B   Uc  [        5       nO [        U[        5      (       a  [        U5      n[	        X5      (       a  SSU  S34$ U S:X  a  [        XU5      $ U [        ;   a/  [        S5        [        SU  S35        [        S5        [        XX#S9$ U (       d  g	S
SU  34$ )an  
Ensure a DiT model is available, downloading if necessary.

Args:
    model_name: Name of the DiT model
    checkpoints_dir: Custom checkpoints directory (optional)
    token: HuggingFace token for private repos (optional)
    prefer_source: Preferred download source ("huggingface", "modelscope", or None for auto-detect)

Returns:
    Tuple of (success, message)
TzDiT model 'r   r   r   r   r   r   )FzEUnknown DiT model: '' (pass None for default or choose a valid model)FzUnknown DiT model: )	r   r:   r;   r   r   r   ry   r   r   )r4   r?   r]   rj   s       r!   ensure_dit_modelr     s    $ -/	OS	)	)/*66{:,n=== (( GG &&oJ<'RSTo Egg]'
|444r    c                  8    [         /[        R                  5       Q$ )z7Return all selectable VAE variant ids (official first).)DEFAULT_VAE_VARIANTr}   r   r   r    r!   list_available_vae_variantsr     s    6,"3"3"566r    checkpoint_dirz
str | Pathvae_variantc           	      B   [        U [        5      (       a  [        U 5      n U(       d  U S-  $ [        R                  R                  U5      (       a  [        U5      $ U[        :X  a  U S-  $ U[        ;   a  X-  $ [        SU SSR                  [        5       5       35      e)a  Resolve a VAE variant id (or absolute path) to its on-disk directory.

Args:
    checkpoint_dir: Root checkpoints directory.
    vae_variant: Variant id (``"official"`` or a key in ``VAE_REGISTRY``)
        or an absolute filesystem path. ``None`` / ``""`` is treated as
        ``"official"``.

Returns:
    Absolute path of the VAE checkpoint directory.

Raises:
    ValueError: If ``vae_variant`` is not recognized.
rz   Unknown VAE variant ''. Available: r   )r:   r;   r   r   pathisabsr   r}   
ValueErrorr   r   )r   r   s     r!   resolve_vae_pathr     s     .#&&n-%%	ww}}[!!K  ))%%l"++

}N99023
4	6 r    c                     Uc  [        5       nO [        U[        5      (       a  [        U5      n [	        X5      n[        U5      $ ! [
         a     gf = f)z=Return whether the requested VAE variant has weights on disk.F)r   r:   r;   r   r   r   r   )r   r?   r   s      r!   check_vae_existsr     sW    -/	OS	)	)/= #4((  s   A 
AAc                    U [         :X  a  SS[          S34$ U [        ;  a6  SR                  [        R                  5       5      =(       d    SnSSU  SU 34$ Uc  [	        5       nO [        U[        5      (       a  [        U5      nUR                  SSS	9  X-  nU(       d  [        U5      (       a
  SSU  S
U 34$ [        U    n[        SU  SU S35        [        SU 35        [        XvX45      $ )u   Download a community VAE variant into ``<checkpoints>/<variant>/``.

The bundled ``"official"`` VAE is *not* downloaded here — it ships
with the main model and is fetched by ``download_main_model``.
FVAE variant 'z?' ships with the main model; use download_main_model() instead.r   z(none)r   r   Trl   r   zDownloading VAE 'z' from r   r   )r   r}   r   r   r   r:   r;   r   rq   r   r   rx   )r   r?   r   r]   rj   r   target_pathr[   s           r!   download_vaer     s    ))/0 11 1
 	
 ,&IIl//12>h	-k].TTT-/	OS	)	)/$6!/K,[99}[M1Ek]SSS;'G	k]''#
>?	M+
'(7FFr    c                    U (       a
  U [         :X  a  [        XU5      $ Uc  [        5       nO [        U[        5      (       a  [        U5      n[        X5      (       a  SSU  S34$ [        R                  R                  U 5      (       a0  [        U 5      nUR                  5       (       d  SSU  S34$ SSU  S34$ [        S5        [        SU  S	35        [        S
5        [        XX#S9$ )a  Ensure the requested VAE variant is on disk, downloading if needed.

For ``"official"`` (or ``None``) this defers to ``ensure_main_model``
since the bundled VAE travels with the main model. For registered
community variants this calls ``download_vae`` when the directory
is missing.
Tr   r   Fz
VAE path 'z' does not exist.zN' does not contain VAE weights (expected diffusion_pytorch_model.safetensors).r   r   r   r   )r   r   r   r:   r;   r   r   r   r   r   r9   r   r   )r   r?   r]   rj   r   s        r!   ensure_vae_modelr     s     +)<< GG-/	OS	)	)/55}[M@@@
 
ww}}[!!K {{}}J{m3DEEE &> >
 	

 
/	M+&Q
RS	/E__r    c                     [        S5        [        S5        [        S5        [        S5        [        S[         35        [        S5        [        S5        [        R                  5        H,  u  pSU R	                  5       ;   d  M  [        S	U  S
U 35        M.     [        S5        [        R                  5        H,  u  pSU R	                  5       ;  d  M  [        S	U  S
U 35        M.     [
        (       aK  [        S5        [        S[         35        [
        R                  5        H  u  p[        S	U  S
U 35        M     [        S5        g)z)Print formatted list of available models.z
Available Models for Download:z<============================================================zB
Supported Sources: HuggingFace Hub <-> ModelScope (auto-fallback)z
[Main Model]z
  main -> zM  Contains: vae, Qwen3-Embedding-0.6B, acestep-v15-turbo, acestep-5Hz-lm-1.7Bz
[Optional LM Models]r   z  rH   z
[Optional DiT Models]z
[Optional VAEs]z  official -> bundled in r   N)r   r   ry   itemsr   r}   )r=   repos     r!   print_model_listr   C  s   	
,-	(O	
OP	
	J'
()	
YZ	
"#'--/
4::<BtfD'( 0 

#$'--/
tzz|#BtfD'( 0 |!")/):;<&,,.JDBtfD'( / 
/r    c                     [         R                  " S[         R                  SS9n U R                  SS[        SS9  U R                  SS	S
SS9  U R                  SSS
SS9  U R                  SS[        SSS9  U R                  SSS
SS9  U R                  SS[        SSS9  U R                  SS
SS9  U R                  5       nUR                  (       a  [        5         gUR                  (       a  [        UR                  5      O	[        5       n[        SU 35        UR                  (       aA  [        X!R                  UR                  5      u  p4U H  n[        U5        M     U(       a  S$ S$ UR                  (       Ga  UR                  S :X  a#  [!        X!R                  UR                  5      u  p5OUR                  ["        ;   a  UR$                  (       dP  ['        U5      (       d@  [        S!5        [!        X!R                  UR                  5      u  pg[        U5        U(       d  g[)        UR                  X!R                  UR                  5      u  p5O$[        S"UR                   35        [        S#5        g[        U5        U(       a  S$ S$ [        S$5        [!        X!R                  UR                  5      u  p5[        U5        U(       a  [        S%5        [        S&U 35        U(       a  S$ S$ )'z&CLI entry point for model downloading.zMDownload ACE-Step models with automatic fallback (HuggingFace <-> ModelScope)a  
Examples:
  acestep-download                          # Download main model (includes LM 1.7B)
  acestep-download --all                    # Download all available models
  acestep-download --model acestep-v15-sft  # Download a specific model
  acestep-download --list                   # List all available models

Network Detection:
  Automatically detects network environment and chooses the best download source:
  - Google accessible -> HuggingFace (fallback to ModelScope)
  - Google blocked -> ModelScope (fallback to HuggingFace)

Shared checkpoints directory:
  Set ACESTEP_CHECKPOINTS_DIR to share models across multiple installations:
  export ACESTEP_CHECKPOINTS_DIR=~/ace-step-models

Alternative using huggingface-cli:
  huggingface-cli download ACE-Step/Ace-Step1.5 --local-dir ./checkpoints
  huggingface-cli download ACE-Step/acestep-5Hz-lm-0.6B --local-dir ./checkpoints/acestep-5Hz-lm-0.6B
        )descriptionformatter_classepilogz--modelz-mz?Specific model to download (use --list to see available models))typehelpz--allz-a
store_truezDownload all available models)actionr   z--listz-lzList all available modelsz--dirz-dNz5Custom checkpoints directory (default: ./checkpoints))r   defaultr   z--forcez-fz&Force re-download even if model existsz--tokenz-tz#HuggingFace token for private reposz--skip-mainzCSkip downloading the main model (only download specified sub-model)r   zCheckpoints directory:    r   z5Main model not found. Downloading main model first...zUnknown model: z"Use --list to see available modelszHDownloading main model (includes vae, text encoder, DiT, and LM 1.7B)...z
Download complete!zModels are available at: )argparseArgumentParserRawDescriptionHelpFormatteradd_argumentr;   
parse_argslistr   dirr   r   allr   r   r]   modelr   ry   	skip_mainr   r   )parserargsr?   r   r   r   main_successmain_msgs           r!   r   r   `  s   $$c <<F2 4N  
 ,  
 $(  
 D	   45  
 42	   R   D yy 8<xx)$((3EXEZO	#O#4
56 xx/TZZXC#J q"" zzz::.

DJJWLGSZZ,,>>*A/*R*RMN)<_jjZ^ZdZd)e&h#,TZZ**VZV`V`aLGSODJJ<0167c
q"" 

TU '

DJJOLG	#J$%)/):;<1Qr    __main__)g      @r   )NN)NFNN)NFN)NNN)NNNN)7__doc__r   sysr+   rJ   r   typingr   r   r   r   pathlibr   logurur   r   r;   __annotations__r"   r3   rF   rN   floatboolrZ   re   ri   rx   r   ry   r   r   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __name__exitr   r    r!   <module>r     s   
 
    . .   !%* ' '$+)03:07#$"&#* S#X *6 6
 # !S !d3i !H%s %S	 %X  2   C= 
	8 
6  #'	B(B(B( C=B( C=	B(
 49B(R )
 :5 C13 C$K97;% 4S> "  )  0 d38n 
 ! $ .HSM .T .$R R R0Xd^ t &/3 /$ /SW /.tCH~  '+#'	0d^00 C=0 C=	0
 490j '+#'11d^1 1 C=	1
 C=1 491j '+%!d^%!%! C=%! 4c?	%!R '+#'Zd^ZC=Z C=Z 49	ZB !%&*#'	+d+dd^+d C=+d C=	+d
 49+d` '+#'	'5'5d^'5 C='5 C=	'5
 49'5T7T#Y 7
\  RV >
)# 
) 
)RV 
) '+#'#G#Gd^#G #G C=	#G
 C=#G 49#GN "&&*#'	(`#(`d^(` C=(` C=	(`
 49(`V:tn zHHTV r    