-
-
Notifications
You must be signed in to change notification settings - Fork 367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
jupyter_ai
import time is too slow
#1115
Comments
@krassowski Thank you for opening an issue about this! I've also noticed that the startup time has slowly worsened over the last year, and I wish I had the time to fix that. Could you / another contributor explore adding debug/info logs that trace the time it takes for the extension to initialize? For example, it'd be great to see what % of the time is spent loading the entry points & entry point groups. We need that data to determine where the slowdown is coming from, and to determine the best fix available. My ability to contribute will be limited, as I need to focus full-time on Jupyter AI v3 very soon. Hope you understand, and I sincerely appreciate your patience as you deal with Jupyter AI issues. 🙏 |
I investigated this issue and found that the startup delay in Jupyter AI is largely due to heavy package imports. For instance, importing several components from langchain.prompts takes around 600ms:
This delay, multiplied by similar imports from other heavy packages, significantly slows down the startup. A recent PR added an async start hook to the Jupyter server extension API (jupyter-server/jupyter_server#1417), which I attempted to leverage. For example:
However, given the number of heavy imports, applying this approach individually may not be feasible. I'm currently exploring better options. Any suggestions or alternative approaches would be greatly appreciated. CC: @krassowski @dlqqq |
I think the "heavy" imports should mostly happen in entry points by definition, including any specific langchain vendor extensions for LLMs, context providers, and all slash command handlers. Currently entrypoints are already used for context providers: jupyter-ai/packages/jupyter-ai/jupyter_ai/extension.py Lines 546 to 548 in 7b4586e
and models: jupyter-ai/packages/jupyter-ai/jupyter_ai/extension.py Lines 369 to 374 in 7b4586e
and custom slash commands: jupyter-ai/packages/jupyter-ai/jupyter_ai/extension.py Lines 495 to 504 in 7b4586e
If we also moved the default slash, which are currently hard-coded: jupyter-ai/packages/jupyter-ai/jupyter_ai/extension.py Lines 481 to 493 in 7b4586e
to be load from entry points, we would not only have a more fine-grained control on the import timing, we would also solve #507 (which was a hurdle in customizing jupyter-ai) I suspect moving entry points to happen |
@Darshan808 Thank you doing research & profiling the performance impact. This is super helpful! Regarding your suggested solution: I'm not sure that it would improve performance. Python imports are inherently synchronous, i.e. they block the Python process & event loop. As far as I can tell, doing an It may be better to investigate if we can improve performance by changing our import paths. We import from langchain_core.output_parsers import StrOutputParser However, take a look at the
|
@krassowski Thanks for the suggestions! Yes I agree, loading entry points asynchronously would definitely bring performance benefits. Right now, I think we're loading all entry points in giant code blocks in the main |
In case if there is some misunderstanding, the issue does not aim to magically make jupyter-ai be ready faster; it marely means to delay loading of its heavy dependencies to happen later. |
Nope, no significant difference: |
@krassowski The example on the left is much faster because it's not doing anything besides creating a coroutine object. The body of Suppose we do move our imports to an async function (i.e. a coroutine). As soon as Jupyter Server awaits that coroutine, the Python process & server event loop is blocked until the imports are complete. This is because the coroutine would not be doing anything actually asynchronous; each This will happen even if
I agree that loading our imports & entry points would improve the UX! I'm not trying to shut down that idea. I'm just stating that I have good reasons for why the suggested approach might not work. Let me see if I can produce an example for this. |
Actually I just realized that jupyter-server/jupyter_server#1417 needs to be released first, before I can provide an example demonstrating my point. |
We should be mindful of the difference between concurrency (doing multiple interrupted tasks in the same thread of execution) and parallelism (doing multiple un-interrupted tasks in separate threads of execution). Async/await just provides concurrency, so it's not obvious how it can mitigate the performance impact of Async/await will be useful if we find a way to asynchronously import Python modules / load entry points. However, I don't know if that is even possible in Python. I'll do some more research later. |
Yes, I see the problem, which is made worse by the async entry point for server extension being awaited in the very next cycle of the IO loop. This behaves differently from what is implemented in jupyter-lsp. This is super promising: https://discuss.python.org/t/async-imports-to-reduce-startup-times/69732/25
|
Here is the thing: we do not actually care about a single import that much, right? As long as we can call |
jupyter_ai
import time is too slow
I've renamed the issue to focus on the speed of importing the |
Description
jupyter-ai
is the slowest extensions of the ones that I am shipping in various deployments. Even worse, it is blocking the jupyter-server from startup. It would be lovely if we could reduce the startup time.Reproduce
jupyter-ai
jupyter server extension list
to get detailed timings, on my laptop it is:as compared to all other extensions being ready instantaneously:
jupyter lab
orjupyter server
jupyter-ai
blocks jupyter-server startup for 2-3 secondsExpected behavior
jupyter-server
async hook once merged Add async start hook to ExtensionApp API jupyter-server/jupyter_server#1417Context
The text was updated successfully, but these errors were encountered: