@@ -135,15 +135,17 @@ pub fn ensure_model_downloaded(repo_id: &str) -> Result<PathBuf> {
135135 let api = builder. build ( ) ?;
136136 let repo = api. model ( repo_id. to_string ( ) ) ;
137137
138- // Download config.json first — validates repo access (fails fast on auth errors ).
138+ // Download config.json (optional — image models like FLUX don't have it ).
139139 log:: info!( "downloading config.json ..." ) ;
140- repo. download ( "config.json" )
141- . map_err ( |e| anyhow ! ( "failed to download config.json from '{}': {}" , repo_id, e) ) ?;
140+ match repo. download ( "config.json" ) {
141+ Ok ( _) => log:: info!( "config.json downloaded" ) ,
142+ Err ( _) => log:: info!( "no config.json (image/diffusion model)" ) ,
143+ }
142144
143145 // Download tokenizer (optional — some models like VibeVoice use external tokenizers).
144146 log:: info!( "downloading tokenizer.json ..." ) ;
145- if let Err ( e ) = repo. download ( "tokenizer.json" ) {
146- log:: warn !( "tokenizer.json not available for '{}': {}" , repo_id , e ) ;
147+ if repo. download ( "tokenizer.json" ) . is_err ( ) {
148+ log:: info !( "no tokenizer.json" ) ;
147149 }
148150
149151 // Try sharded model first (model.safetensors.index.json), fall back to single file.
@@ -178,16 +180,38 @@ pub fn ensure_model_downloaded(repo_id: &str) -> Result<PathBuf> {
178180 }
179181
180182 index_path. parent ( ) . unwrap ( ) . to_path_buf ( )
181- } else {
183+ } else if let Ok ( model_path ) = repo . download ( "model.safetensors" ) {
182184 log:: info!( "downloading model.safetensors ..." ) ;
183- let model_path = repo. download ( "model.safetensors" ) . map_err ( |e| {
184- anyhow ! (
185- "failed to download model from '{}': no index.json and no model.safetensors found: {}" ,
186- repo_id,
187- e
188- )
189- } ) ?;
190185 model_path. parent ( ) . unwrap ( ) . to_path_buf ( )
186+ } else {
187+ // No standard model layout — list repo files and download all .safetensors
188+ // (e.g. FLUX repos use flux1-dev-fp8.safetensors at root)
189+ log:: info!( "no standard model layout, listing repo files..." ) ;
190+ let repo_info = repo. info ( ) . map_err ( |e| {
191+ anyhow ! ( "failed to get repo info for '{}': {}" , repo_id, e)
192+ } ) ?;
193+ let safetensor_files: Vec < & str > = repo_info. siblings . iter ( )
194+ . map ( |s| s. rfilename . as_str ( ) )
195+ . filter ( |f| f. ends_with ( ".safetensors" ) && !f. contains ( '/' ) )
196+ . collect ( ) ;
197+ if safetensor_files. is_empty ( ) {
198+ anyhow:: bail!(
199+ "no .safetensors files found in '{}' — cannot download model" ,
200+ repo_id
201+ ) ;
202+ }
203+ log:: info!( "found {} safetensor files to download" , safetensor_files. len( ) ) ;
204+ let mut snapshot_dir = None ;
205+ for ( i, file) in safetensor_files. iter ( ) . enumerate ( ) {
206+ log:: info!( "[{}/{}] downloading {} ..." , i + 1 , safetensor_files. len( ) , file) ;
207+ let path = repo. download ( file) . map_err ( |e| {
208+ anyhow ! ( "failed to download '{}' from '{}': {}" , file, repo_id, e)
209+ } ) ?;
210+ if snapshot_dir. is_none ( ) {
211+ snapshot_dir = Some ( path. parent ( ) . unwrap ( ) . to_path_buf ( ) ) ;
212+ }
213+ }
214+ snapshot_dir. unwrap ( )
191215 } ;
192216
193217 log:: info!( "model files ready at {}" , snapshot_dir. display( ) ) ;
0 commit comments