Skip to content

Commit ec8da0b

Browse files
committed
Improved Hugging Face Model Downloading Logs
1 parent 4e7e57c commit ec8da0b

File tree

5 files changed

+133
-43
lines changed

5 files changed

+133
-43
lines changed

CHANGELOG.md

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,21 @@
22

33
All notable changes to LocalLab will be documented in this file.
44

5-
## [0.6.2] - 2024-05-04
5+
## [0.6.3] - 2025-05-16
6+
7+
### Improved
8+
9+
- Enhanced model downloading experience by using HuggingFace's native progress bars instead of custom logger
10+
- Fixed issue with Hugging Face download logs being intercepted by custom logger
11+
- Ensured Hugging Face progress bars display in their original, visually appealing format
12+
- Improved configuration of Hugging Face Hub progress bars for better visual experience
13+
- Completely bypassed custom logging for Hugging Face download-related logs
14+
- Configured transformers library to use native progress bars for model downloads
15+
- Disabled logger propagation for HuggingFace-related modules during downloads
16+
- Added proper spacing before and after progress bars for better readability
17+
- Enhanced progress bar detection to catch all download-related progress indicators
18+
19+
## [0.6.2] - 2025-05-04
620

721
### Improved
822

@@ -16,13 +30,13 @@ All notable changes to LocalLab will be documented in this file.
1630
- Updated default values for all optimization settings to be enabled by default
1731
- Ensured consistency between displayed optimization settings and saved configuration
1832

19-
## [0.6.1] - 2024-05-02
33+
## [0.6.1] - 2025-05-02
2034

2135
### Fixed
2236

2337
- Fixed CLI config environment variable issue
2438

25-
## [0.6.0] - 2024-05-02
39+
## [0.6.0] - 2025-05-02
2640

2741
### Added
2842

@@ -39,7 +53,7 @@ All notable changes to LocalLab will be documented in this file.
3953
- Fixed client error with `do_sample` parameter by adding it to all client methods
4054
- Updated client package version to 1.0.9 to reflect these fixes
4155

42-
## [0.5.9] - 2024-05-01
56+
## [0.5.9] - 2025-05-01
4357

4458
### Fixed
4559

@@ -59,7 +73,7 @@ All notable changes to LocalLab will be documented in this file.
5973
- Maintained top and bottom borders for visual separation while removing side borders
6074
- Enhanced overall visual consistency across all banners
6175

62-
## [0.5.8] - 2024-05-01
76+
## [0.5.8] - 2025-05-01
6377

6478
### Added
6579

@@ -92,7 +106,7 @@ All notable changes to LocalLab will be documented in this file.
92106
- Increased retry counts for better reliability
93107
- Added top_k parameter to all generation methods
94108

95-
## [0.5.7] - 2024-05-01
109+
## [0.5.7] - 2025-05-01
96110

97111
### Improved
98112

@@ -103,7 +117,7 @@ All notable changes to LocalLab will be documented in this file.
103117
- Improved overall visual consistency and readability across all UI elements
104118
- Enhanced color scheme for better visual appeal and readability
105119

106-
## [0.5.6] - 2024-05-01
120+
## [0.5.6] - 2025-05-01
107121

108122
### Fixed
109123

@@ -113,15 +127,15 @@ All notable changes to LocalLab will be documented in this file.
113127
- Enhanced logging during model downloads for better readability
114128
- Improved visual clarity of download progress information
115129

116-
## [0.5.5] - 2024-04-30
130+
## [0.5.5] - 2025-04-30
117131

118132
### Fixed
119133

120134
- Fixed extra spacing in the boundary of status banners
121135
- Improved alignment of INITIALIZING and RUNNING status boxes
122136
- Enhanced visual consistency across all UI elements
123137

124-
## [0.5.4] - 2024-04-30
138+
## [0.5.4] - 2025-04-30
125139

126140
### Improved
127141

@@ -131,7 +145,7 @@ All notable changes to LocalLab will be documented in this file.
131145
- Added automatic width adjustment for banners based on content length
132146
- Fine-tuned color scheme to ensure all logs remain visible while not competing with important banners
133147

134-
## [0.5.3] - 2024-04-30
148+
## [0.5.3] - 2025-04-30
135149

136150
### Improved
137151

@@ -149,7 +163,7 @@ All notable changes to LocalLab will be documented in this file.
149163
- Improved overall visual consistency across all UI elements
150164
- Made server status much easier to distinguish at a glance
151165

152-
## [0.5.2] - 2024-04-30
166+
## [0.5.2] - 2025-04-30
153167

154168
### Fixed
155169

@@ -161,7 +175,7 @@ All notable changes to LocalLab will be documented in this file.
161175
- Added proper cleanup of existing handlers before adding new ones
162176
- Improved compatibility with different terminal environments
163177

164-
## [0.5.1] - 2024-04-21
178+
## [0.5.1] - 2025-04-21
165179

166180
### Added
167181

@@ -181,7 +195,7 @@ All notable changes to LocalLab will be documented in this file.
181195
- Added proper timeout handling in streaming operations
182196
- Enhanced connection state management
183197

184-
## [0.5.0] - 2024-04-21
198+
## [0.5.0] - 2025-04-21
185199

186200
### Fixed
187201

@@ -191,15 +205,15 @@ All notable changes to LocalLab will be documented in this file.
191205
- Improved package import reliability
192206
- Ensured both LocalLabClient and SyncLocalLabClient are properly exported
193207

194-
## [0.5.01] - 2024-04-21
208+
## [0.5.01] - 2025-04-21
195209

196210
### Fixed
197211

198212
- Fixed SyncLocalLabClient not being exported from locallab_client package
199213
- Added proper exports for both LocalLabClient and SyncLocalLabClient in package **init**.py
200214
- Ensured both sync and async clients are available through the main package import
201215

202-
## [0.4.50] - 2024-04-21
216+
## [0.4.50] - 2025-04-21
203217

204218
### Changed
205219

@@ -208,7 +222,7 @@ All notable changes to LocalLab will be documented in this file.
208222
- Changed client package structure to use direct imports instead of nested packages
209223
- Improved client package documentation with correct import examples
210224

211-
## [0.4.49] - 2024-04-21
225+
## [0.4.49] - 2025-04-21
212226

213227
### Fixed
214228

@@ -221,7 +235,7 @@ All notable changes to LocalLab will be documented in this file.
221235
- Improved task cancellation with proper timeout handling
222236
- Enhanced force exit mechanism to ensure clean termination
223237

224-
## [0.4.48] - 2024-03-15
238+
## [0.4.48] - 2025-03-15
225239

226240
### Client Library Changes (v0.2.1)
227241

@@ -270,7 +284,7 @@ All notable changes to LocalLab will be documented in this file.
270284
- Removed text cleaning and formatting from all generation endpoints
271285
- Improved error handling in streaming responses
272286

273-
## [0.4.47] - 2024-03-15
287+
## [0.4.47] - 2025-03-15
274288

275289
### Added
276290

@@ -295,7 +309,7 @@ All notable changes to LocalLab will be documented in this file.
295309
- Enhanced Python client with better error handling for streaming
296310
- Added proper error message propagation from server to client
297311

298-
## [0.4.46] - 2024-03-14
312+
## [0.4.46] - 2025-03-14
299313

300314
### Added
301315

@@ -310,7 +324,7 @@ All notable changes to LocalLab will be documented in this file.
310324
- Improved error handling in streaming generation
311325
- Enhanced token cleanup for better readability
312326

313-
## [0.4.45] - 2024-03-14
327+
## [0.4.45] - 2025-03-14
314328

315329
### Fixed
316330

@@ -319,7 +333,7 @@ All notable changes to LocalLab will be documented in this file.
319333
- Bumped client package version to 1.0.2
320334
- Updated documentation with correct client initialization examples
321335

322-
## [0.4.31] - 2024-03-14
336+
## [0.4.31] - 2025-03-14
323337

324338
### Fixed
325339

locallab/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
LocalLab - A lightweight AI inference server for running LLMs locally
33
"""
44

5-
__version__ = "0.6.2" # Updated to improve model downloading experience and fix CLI settings
5+
__version__ = "0.6.3" # Updated to improve model downloading experience and fix CLI settings
66

77
# Only import what's necessary initially, lazy-load the rest
88
from .logger import get_logger

locallab/logger/__init__.py

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -113,30 +113,36 @@ def format(self, record):
113113
# HuggingFace progress bars use tqdm which writes directly to stdout/stderr
114114
# We need to completely bypass our logger for these messages
115115

116+
# First, check if this is a HuggingFace-related log
117+
is_hf_log = False
118+
if hasattr(record, 'name') and isinstance(record.name, str):
119+
# HuggingFace Hub logs typically come from these modules
120+
hf_modules = ['huggingface_hub', 'filelock', 'transformers', 'tqdm', 'accelerate', 'bitsandbytes']
121+
is_hf_log = any(module in record.name for module in hf_modules)
122+
123+
# Also check if the message contains download-related content
124+
is_download_log = False
125+
if hasattr(record, 'msg') and isinstance(record.msg, str):
126+
download_patterns = ['download', 'fetch', 'safetensors', '.bin', '.json', 'model-', 'pytorch_model',
127+
'Fetching', 'files:', 'it/s', 'B/s', '%', 'MB/s', 'GB/s']
128+
is_download_log = any(pattern in str(record.msg).lower() for pattern in download_patterns)
129+
130+
# If this is a HuggingFace download log or tqdm progress bar, skip it completely
131+
# This ensures HuggingFace's native progress bars are displayed correctly
132+
if is_hf_log or is_download_log or (hasattr(record, 'msg') and '%' in str(record.msg) and ('/' in str(record.msg))):
133+
return ""
134+
116135
# Check if we're currently downloading a model
117136
try:
118137
from ..utils.progress import is_model_downloading
119138

120-
# Check if this is a HuggingFace progress bar log
121-
is_hf_progress_log = False
122-
if hasattr(record, 'name') and isinstance(record.name, str):
123-
# HuggingFace Hub logs typically come from these modules
124-
hf_modules = ['huggingface_hub', 'filelock', 'transformers', 'tqdm']
125-
is_hf_progress_log = any(module in record.name for module in hf_modules)
126-
127-
# If we're downloading a model and this is a HuggingFace log, skip our formatting
128-
if is_model_downloading() and is_hf_progress_log:
129-
# Return empty string to skip this log in our logger
130-
# HuggingFace will handle displaying its own progress bars
131-
return ""
132-
133-
# For non-HuggingFace logs during model download, only show critical and model-related logs
134-
elif is_model_downloading() and record.levelno < logging.ERROR:
139+
# During model downloads, only show critical logs and important model-related logs
140+
if is_model_downloading() and record.levelno < logging.ERROR:
135141
# Check if this is a model-related log that should be shown
136142
is_model_log = False
137143
if hasattr(record, 'msg') and isinstance(record.msg, str):
138-
model_patterns = ['model', 'download', 'tokenizer', 'weight']
139-
is_model_log = any(pattern in record.msg.lower() for pattern in model_patterns)
144+
model_patterns = ['model loaded', 'tokenizer loaded', 'loading complete']
145+
is_model_log = any(pattern in str(record.msg).lower() for pattern in model_patterns)
140146

141147
# Skip non-critical and non-model logs during model download
142148
if not is_model_log:

locallab/model_manager.py

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,21 @@
2222
import tempfile
2323
import json
2424

25-
# Configure HuggingFace Hub progress bars
25+
# Configure HuggingFace Hub progress bars to use native display
26+
# This ensures we see the visually appealing progress bars from HuggingFace
2627
configure_hf_hub_progress()
2728

29+
# Also configure transformers to use HuggingFace Hub's progress bars
30+
try:
31+
import transformers
32+
transformers.utils.logging.enable_progress_bar()
33+
# Set transformers logging to only show warnings and errors
34+
transformers.logging.set_verbosity_warning()
35+
except ImportError:
36+
logger.debug("Could not configure transformers progress bars")
37+
except Exception as e:
38+
logger.debug(f"Error configuring transformers progress bars: {str(e)}")
39+
2840
QUANTIZATION_SETTINGS = {
2941
"fp16": {
3042
"load_in_8bit": False,
@@ -274,10 +286,31 @@ async def _load_model_with_optimizations(self, model_id: str):
274286
# Access the module's global variable
275287
import locallab.utils.progress
276288
locallab.utils.progress.is_downloading = True
289+
290+
# Ensure HuggingFace Hub's progress bars are enabled
291+
from huggingface_hub.utils import logging as hf_logging
292+
hf_logging.enable_progress_bars()
293+
294+
# Configure transformers to use progress bars
295+
import transformers
296+
transformers.utils.logging.enable_progress_bar()
297+
298+
# Also ensure tqdm is properly configured for nice display
299+
import tqdm
300+
tqdm.tqdm.monitor_interval = 0 # Disable monitor thread which can cause issues
301+
302+
# Temporarily disable our custom logger for HuggingFace logs
303+
import logging
304+
for logger_name in ['tqdm', 'huggingface_hub', 'transformers', 'filelock']:
305+
logging.getLogger(logger_name).handlers = [] # Remove any handlers
306+
logging.getLogger(logger_name).propagate = False # Don't propagate to parent loggers
277307
except:
278308
# Fallback if import fails
279309
pass
280310

311+
# Add an empty line before progress bars start
312+
print("\n")
313+
281314
# Load tokenizer first
282315
logger.info(f"Loading tokenizer for {model_id}...")
283316
self.tokenizer = AutoTokenizer.from_pretrained(
@@ -1078,10 +1111,31 @@ async def load_custom_model(self, model_name: str, fallback_model: Optional[str]
10781111
# Access the module's global variable
10791112
import locallab.utils.progress
10801113
locallab.utils.progress.is_downloading = True
1114+
1115+
# Ensure HuggingFace Hub's progress bars are enabled
1116+
from huggingface_hub.utils import logging as hf_logging
1117+
hf_logging.enable_progress_bars()
1118+
1119+
# Configure transformers to use progress bars
1120+
import transformers
1121+
transformers.utils.logging.enable_progress_bar()
1122+
1123+
# Also ensure tqdm is properly configured for nice display
1124+
import tqdm
1125+
tqdm.tqdm.monitor_interval = 0 # Disable monitor thread which can cause issues
1126+
1127+
# Temporarily disable our custom logger for HuggingFace logs
1128+
import logging
1129+
for logger_name in ['tqdm', 'huggingface_hub', 'transformers', 'filelock']:
1130+
logging.getLogger(logger_name).handlers = [] # Remove any handlers
1131+
logging.getLogger(logger_name).propagate = False # Don't propagate to parent loggers
10811132
except:
10821133
# Fallback if import fails
10831134
pass
10841135

1136+
# Add an empty line before progress bars start
1137+
print("\n")
1138+
10851139
self.tokenizer = AutoTokenizer.from_pretrained(model_name)
10861140
logger.info(f"Tokenizer loaded successfully")
10871141

locallab/utils/progress.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,27 @@ def configure_hf_hub_progress():
171171
# 3. Make sure we're NOT overriding HuggingFace's progress callback
172172
# This is critical - we want to use their native implementation
173173
from huggingface_hub import file_download
174-
if hasattr(file_download, "_tqdm_callback") and file_download._tqdm_callback == custom_progress_callback:
175-
# Reset to default if we previously set it to our custom callback
174+
if hasattr(file_download, "_tqdm_callback"):
175+
# Reset to default - we don't want any custom callback
176176
file_download._tqdm_callback = None
177177

178-
# 4. Set a flag to indicate we're using HuggingFace's native progress bars
178+
# 4. Ensure HuggingFace Hub's own logging is properly configured
179+
# This ensures HF's own progress bars are displayed correctly
180+
import huggingface_hub
181+
if hasattr(huggingface_hub, "enable_progress_bars"):
182+
huggingface_hub.enable_progress_bars()
183+
184+
# 5. Configure tqdm directly to ensure proper display
185+
import tqdm
186+
tqdm.tqdm.monitor_interval = 0 # Disable monitor thread which can cause issues
187+
188+
# 6. Ensure we're not capturing tqdm output in our logger
189+
# This is critical for allowing tqdm to directly write to stdout
190+
import logging
191+
tqdm_logger = logging.getLogger("tqdm")
192+
tqdm_logger.setLevel(logging.WARNING) # Only show warnings and errors from tqdm
193+
194+
# 7. Set a flag to indicate we're using HuggingFace's native progress bars
179195
global is_downloading
180196
is_downloading = True
181197

0 commit comments

Comments
 (0)