Skip to content

Commit

Permalink
Updates to hello_world example (#583)
Browse files Browse the repository at this point in the history
* updates hello world example

* incorporating feedback from @ekzhang
  • Loading branch information
charlesfrye authored Feb 14, 2024
1 parent 8a15606 commit b3a3775
Showing 1 changed file with 67 additions and 46 deletions.
113 changes: 67 additions & 46 deletions 01_getting_started/hello_world.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
# # Hello, world!
#
# This is a trivial example of a Modal function, but it illustrates a few features:
# This tutorial demonstrates some core features of Modal:
#
# * You can print things to stdout and stderr.
# * You can return data.
# * You can map over a function.
# * You can run functions on Modal just as easily as you run them locally.
# * Running functions in parallel on Modal is simple and fast.
# * Logs and errors show up immediately, even for functions running on Modal.
#
# ## Import Modal and define the app
# ## Importing Modal and setting up
#
# Let's start with the top level imports.
# You need to import Modal and define the app.
# A stub is an object that defines everything that will be run.
# We start by importing `modal` and creating a `Stub`.
# We build up from our `Stub` to [define our application](/docs/guide/apps).

import sys

Expand All @@ -20,10 +19,18 @@

# ## Defining a function
#
# Here we define a Modal function using the `modal.function` decorator.
# The body of the function will automatically be run remotely.
# This particular function is pretty silly: it just prints "hello"
# and "world" alternatingly to standard out and standard error.
# Modal takes code and runs it in the cloud.
#
# So first we've got to write some code.
#
# Let's write a simple function:
# log `"hello"` to standard out if the input is even
# or `"world"` to standard error if it's not,
# then return the input times itself.
#
# To make this function work with Modal, we just wrap it in a decorator
# from our application `stub`,
# [`@stub.function`](docs/reference/modal.Stub#function).


@stub.function()
Expand All @@ -36,68 +43,82 @@ def f(i):
return i * i


# ## Running it
# ## Running our function locally, remotely, and in parallel
#
# Finally, let's actually invoke it.
# We put this invocation code inside a `@stub.local_entrypoint()`.
# This is because this module will be imported in the cloud, and we don't want
# this code to be executed a second time in the cloud.
# Now let's see three different ways we can call that function:
#
# Run `modal run hello_world.py` and the `@stub.local_entrypoint()` decorator will handle
# starting the Modal app and then executing the wrapped function body.
# 1. As a regular `local` call on your computer, with `f.local`
#
# Inside the `main()` function body, we are calling the function `f` in three ways:
# 2. As a `remote` call that runs in the cloud, with `f.remote`
#
# 1 As a simple local call, `f.local(1000)`
# 2. As a simple *remote* call `f.remote(1000)`
# 3. By mapping over the integers `0..19`
# 3. By `map`ping many copies of `f` in the cloud over many inputs, with `f.map`
#
# We call `f` in each of these ways inside a `main` function below.


@stub.local_entrypoint()
def main():
# Call the function locally.
# run the function locally
print(f.local(1000))

# Call the function remotely.
# run the function remotely on Modal
print(f.remote(1000))

# Parallel map.
# run the function in parallel and remotely on Modal
total = 0
for ret in f.map(range(20)):
total += ret

print(total)


# ## What happens?
# Enter `modal run hello_world.py` in a shell and you'll see
# a Modal app initialize.
# You'll then see the `print`ed logs of
# the `main` function and, mixed in with them, all the logs of `f` as it is run
# locally, then remotely, and then remotely and in parallel.
#
# That's all triggered by adding the [`@stub.local_entrypoint`](docs/reference/modal.Stub#local_entrypoint) decorator on `main`,
# which defines it as the function to start from locally when we invoke `modal run`.
#
# When you do `.remote` on function `f`, Modal will execute `f` **in the cloud,**
# not locally on your computer. It will take the code, put it inside a
# container, run it, and stream all the output back to your local
# computer.
# ## What just happened?
#
# Try doing one of these things next.
# When we called `.remote` on `f`, the function was executed
# **in the cloud**, on Modal's infrastructure, not locally on our computer.
#
# ### Change the code and run again
# In short, we took the function `f`, put it inside a container,
# sent it the inputs, and streamed back the logs and outputs.
#
# For instance, change the `print` statement in the function `f`.
# You can see that the latest code is always run.
# ## But why does this matter?
#
# Try doing one of these things next to start seeing the full power of Modal!
#
# ### You can change the code and run it again
#
# For instance, change the `print` statement in the function `f`
# to print `"spam"` and `"eggs"` instead and run the app again.
# You'll see that that your new code is run with no extra work from you --
# and it should even run faster!
#
# Modal's goal is to make running code in the cloud feel like you're
# running code locally. You don't need to run any commands to rebuild,
# push containers, or go to a web UI to download logs.
# running code locally. That means no waiting for long image builds when you've just moved a comma,
# no fiddling with container image pushes, and no context-switching to a web UI to inspect logs.
#
# ### You can map over more data
#
# Change the `map` range from `20` to some large number, like `1170`. You'll see
# Modal create and run even more containers in parallel this time.
#
# ### Map over a larger dataset
# And it'll happen lightning fast!
#
# Change the map range from 20 to some large number. You can see that
# Modal will create and run more containers in parallel.
# ### You can run a more interesting function
#
# The function `f` is obviously silly and doesn't do much, but you could
# imagine something more significant, like:
# The function `f` is obviously silly and doesn't do much, but in its place
# imagine something that matters to you, like:
#
# * Training a machine learning model
# * Transcoding media
# * Backtesting a trading algorithm.
# * Running [language model inference](/docs/examples/vllm_mixtral) or [fine-tuning](/docs/examples/slack-finetune)
# * Manipulating [audio](/docs/examples/discord-musicgen) or [images](stable_diffusion_xl_turbo)
# * [Collecting financial data](/docs/examples/fetch_stock_prices) to backtest a trading algorithm.
#
# Modal lets you parallelize that operation trivially by running hundreds or
# Modal lets you parallelize that operation effortlessly by running hundreds or
# thousands of containers in the cloud.

0 comments on commit b3a3775

Please sign in to comment.