Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2024-02-18 - Pre-scaled Audio Feedback
**Learning:** AudioFeedback volume scaling was applied during every playback, causing unnecessary numpy overhead and latency.
**Action:** Pre-calculate scaled audio during `_load_and_cache` to minimize `_play_cached` latency (from ~1ms to ~0.04ms).

## 2025-05-18 - Unlocked Garbage Collection
**Learning:** `ParakeetManager` held the model lock during `gc.collect()`, forcing concurrent `transcribe` requests (which require the lock) to wait for full GC completion before they could even *start* reloading the model.
**Action:** Release the lock before calling `gc.collect()`. This allows `transcribe` to acquire the lock and begin `load_model` (which releases GIL for C++ ops) in parallel with the garbage collection of the old model.
6 changes: 5 additions & 1 deletion src/chirp/parakeet_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,15 @@ def _monitor_loop(self) -> None:
self._unload_model()

def _unload_model(self) -> None:
should_collect = False
with self._lock:
if self._model is not None and (time.time() - self._last_access > self._timeout):
self._logger.info("Unloading Parakeet model to free memory.")
self._model = None
gc.collect()
should_collect = True

if should_collect:
gc.collect()

def ensure_loaded(self):
with self._lock:
Expand Down