Skip to content

Instantly share code, notes, and snippets.

@tvst
Last active May 10, 2024 09:06
Show Gist options
  • Save tvst/919abd4a1c229437be91aae80f08437c to your computer and use it in GitHub Desktop.
Save tvst/919abd4a1c229437be91aae80f08437c to your computer and use it in GitHub Desktop.
Simple way to run heavy computations without slowing down other Streamlit users
import streamlit as st
import concurrent.futures # We'll do computations in separate processes!
import mymodule # This is where you'll do the computation
# Your st calls must go inside this IF block.
if __name__ == '__main__':
st.write("Starting a long computation on another process")
# Pick max number of concurrent processes. Depends on how heavy your computation is, and how
# powerful your machine is.
MAX_WORKERS = 50
@st.cache_resource
def get_executor():
return concurrent.futures.ProcessPoolExecutor(max_workers=MAX_WORKERS)
future = get_executor().submit(
# Function to run on a separate process.
mymodule.some_heavy_computation,
# Arguments to pass to the function above.
a=100, b=200, c=300)
# Wait for result.
result = future.result()
st.write("Here's the result of that computation:", result)
@tvst
Copy link
Author

tvst commented May 2, 2024

Same thing but with Ray, so you can easily run tasks on separate machines:

import streamlit as st
import ray  # We'll do computations in separate processes!
import mymodule  # This is where you'll do the computation

# Your st calls must go inside this IF block.
if __name__ == '__main__':
    st.write("Starting a long computation on another process")

    @st.cache_resource
    def initialize_ray():
        # You can configure this init call to point to a separate machine.
        ray.init()

    initialize_ray()

    # Call the heavy function in a subprocess.
    future = mymodule.some_heavy_computation.remote(a=100, b=200, c=300)

    # Wait for result.
    result = ray.get(future)

    st.write("Here's the result of that computation:", result)

Then in mymodule.py you do this:

import ray

@ray.remote(num_cpus=50)
def some_heavy_computation(a, b, c):
    # Do something
    return a * b * c

@tvst
Copy link
Author

tvst commented May 2, 2024

Also: keep in mind Numpy can get absurdly slower when running in multiple processes on the same machine.

If you notice this, you should wrap you Numpy code in this with block:

import threadpoolctl

with threadpoolctl.threadpool_limits(limits=1, user_api='blas'):
	# Numpy code goes here 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment