Ray Distributed Framework
Ray is a unified open-source framework for building and scaling distributed applications and AI workloads in Python. It provides simple APIs for parallelizing Python functions and classes (tasks and actors) and a toolkit of specialized libraries (Ray Data, Train, Tune, Serve, RLlib) for machine learning. Ray offers a universal compute layer for orchestrating clusters, scheduling processes, fault tolerance, and autoscaling. The project maintains a very frequent release cadence, with minor and patch releases occurring every few weeks.
Warnings
- breaking Ray 2.52.0 (released in early 2026) officially ended support for Python 3.9. Users on Python 3.9 must upgrade to Python 3.10 or newer to use current and future Ray versions.
- breaking Ray plans to drop support for Pydantic V1 starting with version 2.56.0. If your project uses Pydantic V1, you will need to migrate to Pydantic V2 to remain compatible with Ray.
- breaking Ray Train V2 is now enabled by default starting from Ray 2.51.0. This introduces significant API changes and improvements, particularly affecting the `Trainer.restore` API. Existing Ray Train users should consult the migration guide.
- gotcha In Ray Data 2.50.0, the default shuffle strategy for aggregations changed from sort-based to hash-based. While intended for lower memory usage and improved performance, this might alter behavior or performance characteristics if you relied on the previous sort-based default.
- gotcha Ray includes built-in token authentication for enhanced security across its components (dashboard, CLI, API clients, internal services). However, this feature is initially off by default and requires explicit configuration to enable.
Install
-
pip install ray -
pip install "ray[data,train,tune,serve,rllib]"
Imports
- ray
import ray
- remote
@ray.remote
Quickstart
import ray
import time
import os
# Initialize Ray (connects to an existing cluster or starts a local one)
# For a cluster, you might use ray.init(address="auto") or specify an address.
# For local testing, ray.init() is sufficient.
ray.init(address=os.environ.get('RAY_ADDRESS', None), ignore_reinit_error=True)
@ray.remote
def fibonacci(n):
if n <= 1:
return n
return fibonacci.remote(n - 1) + fibonacci.remote(n - 2)
@ray.remote
def slow_square(x):
time.sleep(1) # Simulate a slow computation
return x * x
if __name__ == '__main__':
print("--- Ray Tasks Example ---")
# Run tasks in parallel
futures = [slow_square.remote(i) for i in range(5)]
results = ray.get(futures)
print(f"Results from slow_square: {results}")
# Example of recursive Ray tasks (note: fibonacci is a common but inefficient example for Ray's overhead)
# For larger N, this can quickly create too many tasks.
# result_fib = ray.get(fibonacci.remote(10))
# print(f"Fibonacci(10) using Ray: {result_fib}")
print("Ray initialized successfully, dashboard at:", ray.get_dashboard_url())
ray.shutdown()
print("Ray shutdown.")