-
Notifications
You must be signed in to change notification settings - Fork 472
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
Experimental - Stateful code interpreter #326
Conversation
|
aaa11fb
to
099811a
Compare
099811a
to
ea8b13a
Compare
User feedback we've received so far:
|
UPDATE: This has been much improved in the latest version
BenchmarksI did a basic benchmarking of the new Code Interpreter 2.0 SDK and compared it to our production SDK. All in JS. It's not completely fair comparison because there's no Code Interpreter 2.0 SDK
Code import { CodeInterpreterV2 } from 'e2b'
const iterations = 100;
let createSandboxTime = 0;
let execPythonXEquals1Time = 0;
let execPythonXPlusEquals1Time = 0;
let sandboxCloseTime = 0;
for (let i = 0; i < iterations; i++) {
console.log('Iteration:', i + 1)
let startTime = performance.now();
const sandbox = await CodeInterpreterV2.create();
createSandboxTime += performance.now() - startTime;
startTime = performance.now();
await sandbox.execPython('x = 1');
execPythonXEquals1Time += performance.now() - startTime;
startTime = performance.now();
const result = await sandbox.execPython('x+=1; x');
execPythonXPlusEquals1Time += performance.now() - startTime;
startTime = performance.now();
await sandbox.close();
sandboxCloseTime += performance.now() - startTime;
}
console.log(`Average Create Sandbox Time: ${createSandboxTime / iterations}ms`);
console.log(`Average Execute Python x = 1 Time: ${execPythonXEquals1Time / iterations}ms`);
console.log(`Average Execute Python x+=1; x Time: ${execPythonXPlusEquals1Time / iterations}ms`);
console.log(`Average Sandbox Close Time: ${sandboxCloseTime / iterations}ms`); Results
Production SDK
Code import * as e2b from 'e2b'
const iterations = 100;
let createSandboxTime = 0;
let execPythonXEquals1Time = 0;
let execPythonXPlusEquals1Time = 0;
let sandboxCloseTime = 0;
for (let i = 0; i < iterations; i++) {
console.log('Iteration:', i + 1)
let startTime = performance.now();
const sandbox = await e2b.Sandbox.create();
createSandboxTime += performance.now() - startTime;
startTime = performance.now();
await sandbox.process.startAndWait('python3 -c "x = 1"');
execPythonXEquals1Time += performance.now() - startTime;
startTime = performance.now();
await sandbox.process.startAndWait('python3 -c "x+=1; print(x)"');
execPythonXPlusEquals1Time += performance.now() - startTime;
startTime = performance.now();
await sandbox.close();
sandboxCloseTime += performance.now() - startTime;
}
console.log(`Average Sandbox Creation Time: ${createSandboxTime / iterations}ms`);
console.log(`Average Process Start and Wait (x=1) Time: ${execPythonXEquals1Time / iterations}ms`);
console.log(`Average Process Start and Wait (x+=1; print(x)) Time: ${execPythonXPlusEquals1Time / iterations}ms`);
console.log(`Average Sandbox Close Time: ${sandboxCloseTime / iterations}ms`); Results
Difference
|
Thanks for the great work, it seems to be working for the most part. I have a quick bug that might come up in the future. I'm using JS SDK. When I create the sandbox with no initial |
Hey @im-calvin thank you for catching this. We're moving the code interpreter SDK to a separate repository. We'll publish it as a separate package. The rest of the work and all the fixes will be there. |
@@ -0,0 +1,268 @@ | |||
import { Sandbox, SandboxOpts } from '../sandbox' | |||
import { ProcessMessage } from '../sandbox/process' | |||
import { randomBytes } from 'crypto' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use web crypto for edge environment support (cf workers)
} | ||
|
||
private async getKernelID() { | ||
return await this.filesystem.read('/root/.jupyter/kernel_id') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return await this.filesystem.read('/root/.jupyter/kernel_id') | |
return (await this.filesystem.read('/root/.jupyter/kernel_id')).trim(); |
There was an extra newline at the end on cloudflare workers durable objects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @lawrencecchen , all the fixes will be incorporated in this repo https://github.com/e2b-dev/code-interpreter
@lawrencecchen you can start using the new SDK https://github.com/e2b-dev/code-interpreter JavaScript
Python
|
Stateful code interpreter
The current version of the code interpreter SDK allows to run Python code but each run has its own separate context. That means that subsequent runs can't reference to variables, definitions, etc from past code execution runs.
This is suboptimal for a lot of Python use cases with LLMs. Especially GPT-3.5 and 4 expects it runs in a Jupyter Notebook environment. Even when ones tries to convince it otherwise. In practice, LLMs will generate code blocks which have references to previous code blocks. This becomes an issue if a user wants to execute each code block separately which often is the use case.
This new code interpreter template runs a Jupyter server inside the sandbox, which allows for sharing context between code executions.
Additionally, this new template also partly implements the Jupyter Kernel messaging protocol. This means that, for example, support for plotting charts is now improved and we don't need to do hack-ish solutions like in the current production version of our code interpreter.
Current state
Known limited in features such as:
We'll be updating this PR with new releases as we gather more user feedback.
Installation
Install the experimental release candidate
Python
JavaScript
Examples
Minimal example with the sharing context:
Python
JavaScript
Get charts and any display-able data
Python
JavaScript
Streaming code output
Python
JavaScript
Pre-installed Python packages inside the sandbox
The full and always up-to-date list can be found in the
requirements.txt
file.Custom template using Code Interpreter
If you're using a custom sandbox template, you currently need to go through a bit of a manual setup:
jupyter_server_config.py
andstart-up.sh
from this PRcurl
andjq
in your Dockerfile or just addRUN apt-get update && apt-get install -y --no-install-recommends curl jq
-c "/home/user/.jupyter/start-up.sh"
toe2b template build
command or add this line to youre2b.toml
.start_cmd = "/home/user/.jupyter/start-up.sh"