Shared volumes

Modal lets you create writeable volumes that can be simultaneously attached to multiple Modal functions. These are helpful for use cases such as:

  1. Caching model checkpoints
  2. Storing datasets
  3. Keeping a shared cache for expensive computations

Basic example

The modal.SharedVolume constructor initializes an empty volume. This can be mounted within a function by providing a mapping between mount paths and SharedVolume objects. For example, to use a SharedVolume to initialize a shared diskcache:

import modal

stub = modal.Stub(image=modal.Image.debian_slim().pip_install(["diskcache"]))

if stub.is_inside():
    import diskcache as dc

    cache = dc.Cache("/root/foo")

@stub.function(shared_volumes={"/root/foo": modal.SharedVolume()})
def expensive_computation(key: str):
    cached = cache.get(key)

    if cached is not None:
        return cached

    # populate_value
    ...

Persisting volumes

By default, a modal.SharedVolume lives as long as the app it’s defined in, just like any other Modal object. However in many situations you might want to persist the cache between runs of the app. To do this, you can use the persist method on the SharedVolume object. For example, to avoid re-downloading a HuggingFace model checkpoint every time you run your function:

import modal

volume = modal.SharedVolume().persist("model-cache-vol")

stub = modal.Stub()

CACHE_DIR = "/cache"

@stub.function(
    shared_volumes={CACHE_DIR: volume},
    # Set the transformers cache directory to the volume we created above.
    # For details, see https://huggingface.co/transformers/v4.0.1/installation.html#caching-models
    secret=modal.Secret({"TRANSFORMERS_CACHE": CACHE_DIR})
)
def run_inference():
    ...

Further examples

For a complete example that uses modal.SharedVolume, see News Article Summarizer.