perf: lazy-import litellm, faiss, torch to speed up import lotus - #268
Open
01luyicheng wants to merge 1 commit into
Open
perf: lazy-import litellm, faiss, torch to speed up import lotus#26801luyicheng wants to merge 1 commit into
01luyicheng wants to merge 1 commit into
Conversation
Closes lotus-data#143. `import lotus` currently takes ~4s (issue lotus-data#143) because litellm (~4s), torch, sentence_transformers, and faiss are all loaded eagerly at import time. In environments with all optional backends installed, the combined import time can reach ~10s. This PR defers all of them until they are actually needed. Changes: - lotus/models/__init__.py: keep LM / RM / Reranker (base) eager so existing type annotations keep working; load SentenceTransformersRM / CrossEncoderReranker / LiteLLMRM / ColBERTv2RM lazily via PEP 562 __getattr__. - lotus/vector_store/__init__.py: keep VS (base) eager; load FaissVS / WeaviateVS / QdrantVS lazily. - lotus/models/lm.py: add `from __future__ import annotations` and defer all litellm imports (batch_completion, AuthenticationError, ModelResponse, Choices, ChoiceLogprobs, decode/encode/token_counter, supports_reasoning) to the methods that use them. litellm is ~4s and only needed when an LM is actually called, not at `import lotus` time. - lotus/pricing.py: defer litellm / completion_cost to inside calculate_cost_from_response. - lotus/types.py: add `from __future__ import annotations` and move ChatCompletionTokenLogprob to TYPE_CHECKING (only used in dataclass annotations). - tests/test_import_lazy.py: assert litellm, torch, sentence_transformers, faiss are absent from sys.modules after `import lotus`, and that all public names still resolve. - tests/test_lm.py: update mock path from `lotus.models.lm.batch_completion` to `litellm.batch_completion` (the symbol is no longer a module-level attribute of lotus.models.lm after lazy-importing). Result: `import lotus` drops from ~10.5s to ~1.1s (9.6x) in an environment with all backends installed, and from ~4s to ~1s with only litellm installed. The remaining ~1s is dominated by openai (~0.6s) and pandas (~0.2s), which are out of scope for this PR. LM stays eager because it is referenced as a type annotation (lotus.models.LM) in lotus/settings.py and lotus/sem_ops/*.py; making it lazy would require from __future__ import annotations across many files, out of scope for this PR.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose
Closes #143.
import lotuscurrently takes ~4s (per issue #143), and up to ~10s in environments where all optional backends (torch, sentence_transformers, faiss) are installed. The root cause is thatlotus/models/lm.py,lotus/pricing.py,lotus/types.py,lotus/models/__init__.py, andlotus/vector_store/__init__.pyall eagerly import heavy dependencies (litellm~4s,torch,sentence_transformers,faiss) atimport lotustime, even when the user never instantiates anLMor a vector store.This PR defers all of those imports until they are actually needed.
Test Plan
Test Results
Import time (same environment, all backends installed):
import lotuslitellmloadedtorchloadedsentence_transformersloadedfaissloadedIn an environment with only
litellminstalled (no torch/st/faiss, matching the issue reporter's setup),import lotusdrops from ~4s to ~1s.pytest:
tests/test_import_lazy.py: 8 passed (asserts litellm/torch/st/faiss absent fromsys.modulesafterimport lotus; verifies public API still resolves; covers__getattr__cache +AttributeErrorcontract)tests/test_lm.py::TestLM::test_lm_rate_limiting_with_mock: passed (mock path updated fromlotus.models.lm.batch_completiontolitellm.batch_completion)tests/test_lm.py: 4 remaining failures are pre-existing and unrelated to this PR — they requireOPENAI_API_KEYcredentials (Missing credentialserror) and fail onmainas well.ruff check/ruff format --check: clean on all changed files.(Optional) Documentation Update
No public API changes.
from lotus.models import LM,from lotus.models import SentenceTransformersRM,from lotus.vector_store import FaissVS, etc. all continue to work unchanged (now resolved lazily via PEP 562__getattr__).Type of Change
Checklist
BEFORE SUBMITTING, PLEASE READ https://github.com/lotus-data/lotus/blob/main/CONTRIBUTING.md