diff --git a/README.md b/README.md index 4a5310adbbd9..20ac55b188da 100644 --- a/README.md +++ b/README.md @@ -1,68 +1,37 @@ -> **[Sign up on our console](https://console.unify.ai/)** for pilot access! - ------------------------------------------------------------------------ -
- - - - - - - - - - - - - - - - - - - -
- ------------------------------------------------------------------------- - -# Status - -
- - - - - - - - - - - - +
- - + + + + + + + + - - + + - - + +

------------------------------------------------------------------------- +# Convert ML Models Between Frameworks + +Ivy is an open-source machine learning framework that enables you to: -# Unified AI +- Use your ML models and/or functions in any framework by converting any code from one framework to another using `ivy.transpile` +- Convert entire ML models and libraries between frameworks by generating identical source code in any frameworkusing `ivy.source_to_source` *(currently in private beta)*
@@ -89,32 +58,7 @@
------------------------------------------------------------------------- - -Ivy is an open-source machine learning framework that -enables you to: - -- 🔄 **Convert code into any framework**: Use and build on top of any model, library, or device by converting any code from one framework to another using `ivy.transpile`. -- ⚒️ **Write framework-agnostic code**: Write your code once in `ivy` and then choose the most appropriate ML framework as the backend to leverage all the benefits and tools. - -[Join our growing community](https://discord.com/invite/sXyFF8tDtm) 🌍 to connect with people using Ivy. **Let\'s** [unify.ai](https://unify.ai) **together 🦾** - ------------------------------------------------------------------------- - -# Getting started - -[Ivy's transpiler](https://unify.ai/docs/ivy/overview/design/ivy_as_a_transpiler.html) helps you convert code between different ML frameworks. To get pilot access to the transpiler, [sign up](https://console.unify.ai/) and generate an API key. The [Get Started](https://unify.ai/docs/ivy/overview/get_started.html) notebook should help you set up your API key and the [Quickstart](https://unify.ai/docs/ivy/demos/quickstart.html) notebook should give you a brief idea of the features! - -The most important notebooks are: - -- [How to convert your code between frameworks?](https://unify.ai/docs/ivy/demos/learn_the_basics/04_transpile_code.html) -- [How to write framework-agnostic code?](https://unify.ai/docs/ivy/demos/learn_the_basics/01_write_ivy_code.html) - -Beyond that, based on the frameworks you want to convert code between, there are a few more [examples](#using-ivy) further down this page 👇 which contain a number of models and libraries transpiled between PyTorch, JAX, TensorFlow and NumPy. - ------------------------------------------------------------------------- - -## Installing ivy +# Installing ivy The easiest way to set up Ivy is to install it using **pip**: @@ -130,8 +74,8 @@ users who would want to test `ivy` with multiple frameworks at once can use our You can pull the images from: ``` bash -docker pull unifyai/ivy:latest # CPU -docker pull unifyai/ivy:latest-gpu # GPU +docker pull transpileai/ivy:latest # CPU +docker pull transpileai/ivy:latest-gpu # GPU ``` @@ -144,23 +88,40 @@ the latest changes, but we can\'t ensure everything will work as expected 😅 ``` bash -git clone https://github.com/unifyai/ivy.git +git clone https://github.com/ivy-llc/ivy.git cd ivy pip install --user -e . ``` If you want to set up testing and various frameworks it\'s probably best -to check out the [Setting Up](https://unify.ai/docs/ivy/overview/contributing/setting_up.html) +to check out the [Setting Up](https://ivy.dev/docs/overview/contributing/setting_up.html) page, where OS-specific and IDE-specific instructions and video tutorials to do so are available! ------------------------------------------------------------------------- -## Using Ivy +# Getting started + +- [Website](https://ivy.dev) +- [Docs](https://ivy.dev/docs) +- [Demos](https://ivy.dev/demos) +- [Design](https://ivy.dev/docs/overview/design.html) +- [FAQ](https://ivy.dev/docs/overview/faq.html) -After installing Ivy, you can start using it straight away, for example: +[Ivy's transpiler](https://ivy.dev/docs/overview/design/ivy_as_a_transpiler.html) allows you convert code between different ML frameworks. Have a look at our [Quickstart](https://ivy.dev/docs/demos/quickstart.html) notebook to get a brief idea of the features! + +The most important notebooks are: + +- [How to convert your code between frameworks?](https://ivy.dev/docs/demos/learn_the_basics/04_transpile_code.html) +- [How to write framework-agnostic code?](https://ivy.dev/docs/demos/learn_the_basics/01_write_ivy_code.html) + +Beyond that, based on the frameworks you want to convert code between, there are a few more [examples](#using-ivy) further down this page 👇 which contain a number of models and libraries transpiled between PyTorch, JAX, TensorFlow and NumPy. + + +# Using ivy + +After installing ivy, you can start using it straight away, for example:
Transpiling any code from one framework to another @@ -208,7 +169,7 @@ After installing Ivy, you can start using it straight away, for example: \ -The [Examples page](https://unify.ai/demos/) features a wide range of +The [Examples page](https://ivy.dev/docs/demos/) features a wide range of demos and tutorials showcasing the functionalities of Ivy along with multiple use cases, but feel free to check out some shorter framework-specific examples here ⬇️ @@ -1083,245 +1044,35 @@ out = np_loss(p, t)
-
- -I'm using Ivy  - -Or you can use Ivy as a framework, breaking yourself (and your code) -free from deciding which community to support, allowing anyone to run -your code in their framework of choice! - -``` python -import ivy - -# A simple image classification model -class IvyNet(ivy.Module): - def __init__( - self, - h_w=(32, 32), - input_channels=3, - output_channels=512, - num_classes=2, - data_format="NCHW", - device="cpu", - ): - self.h_w = h_w - self.input_channels = input_channels - self.output_channels = output_channels - self.num_classes = num_classes - self.data_format = data_format - super().__init__(device=device) - - def _build(self, *args, **kwargs): - self.extractor = ivy.Sequential( - ivy.Conv2D(self.input_channels, 6, [5, 5], 1, "SAME", data_format=self.data_format), - ivy.GELU(), - ivy.Conv2D(6, 16, [5, 5], 1, "SAME", data_format=self.data_format), - ivy.GELU(), - ivy.Conv2D(16, self.output_channels, [5, 5], 1, "SAME", data_format=self.data_format), - ivy.GELU(), - ) - - self.classifier = ivy.Sequential( - # Since the padding is "SAME", this would be image_height x image_width x output_channels - ivy.Linear(self.h_w[0] * self.h_w[1] * self.output_channels, 512), - ivy.GELU(), - ivy.Linear(512, self.num_classes), - ) - - def _forward(self, x): - x = self.extractor(x) - # flatten all dims except batch dim - x = ivy.flatten(x, start_dim=1, end_dim=-1) - logits = self.classifier(x) - probs = ivy.softmax(logits) - return logits, probs -``` - -After building your model in Ivy, you can set your favourite framework -as the backend to use its operations under the hood! - -``` python -ivy.set_backend("torch") -model = IvyNet() -x = torch.randn(1, 3, 32, 32) -logits, probs = model(x) -``` - -``` python -ivy.set_backend("tensorflow") -model = IvyNet() -x = tf.random.uniform(shape=(1, 3, 32, 32)) -logits, probs = model(x) -``` - -``` python -ivy.set_backend("jax") -model = IvyNet() -x = jax.random.uniform(key, shape=(1, 3, 32, 32)) -logits, probs = model(x) -``` - -``` python -ivy.set_backend("numpy") -model = IvyNet() -x = np.random.uniform(size=(1, 3, 32, 32)) -logits, probs = model(x) -``` - -Last but not least, we can also build the training pipeline in pure ivy -⬇️ - -
-Let's define some helper functions first - -``` python -# helper function for loading the dataset in batches -def generate_batches(images, classes, dataset_size, batch_size=32): - if batch_size > dataset_size: - raise ivy.utils.exceptions.IvyError("Use a smaller batch size") - for idx in range(0, dataset_size, batch_size): - yield images[idx : min(idx + batch_size, dataset_size)], classes[ - idx : min(idx + batch_size, dataset_size) - ] - - -# helper function to get the number of current predictions -def num_correct(preds, labels): - return (preds.argmax() == labels).sum().to_numpy().item() - - -# define a loss function -def loss_fn(params): - v, model, x, y = params - _, probs = model(x, v=v) - return ivy.cross_entropy(y, probs), probs -``` - -
- -
-And train this model! - -``` python -# train the model on gpu if it's available -device = "gpu:0" if ivy.gpu_is_available() else "cpu" - -# training hyperparams -optimizer = ivy.Adam(1e-4) -batch_size = 4 -num_epochs = 20 -num_classes = 10 - -model = IvyNet( - h_w=(28, 28), - input_channels=1, - output_channels=120, - num_classes=num_classes, - device=device, -) - -images = ivy.random_uniform(shape=(16, 1, 28, 28)) -classes = ivy.randint(0, num_classes - 1, shape=(16,)) - - -# training loop -def train(images, classes, epochs, model, device, num_classes=10, batch_size=32): - # training metrics - epoch_loss = 0.0 - metrics = [] - dataset_size = len(images) - - for epoch in range(epochs): - train_correct = 0 - train_loop = tqdm( - generate_batches(images, classes, len(images), batch_size=batch_size), - total=dataset_size // batch_size, - position=0, - leave=True, - ) - - for xbatch, ybatch in train_loop: - xbatch, ybatch = xbatch.to_device(device), ybatch.to_device(device) - - # Since the cross entropy function expects the target classes to be in one-hot encoded format - ybatch_encoded = ivy.one_hot(ybatch, num_classes) - - # update model params - loss_probs, grads = ivy.execute_with_gradients( - loss_fn, - (model.v, model, xbatch, ybatch_encoded), - ) - - model.v = optimizer.step(model.v, grads["0"]) - - batch_loss = ivy.to_numpy(loss_probs[0]).mean().item() # batch mean loss - epoch_loss += batch_loss * xbatch.shape[0] - train_correct += num_correct(loss_probs[1], ybatch) - - train_loop.set_description(f"Epoch [{epoch + 1:2d}/{epochs}]") - train_loop.set_postfix( - running_loss=batch_loss, - accuracy_percentage=(train_correct / dataset_size) * 100, - ) - - epoch_loss = epoch_loss / dataset_size - training_accuracy = train_correct / dataset_size - - metrics.append([epoch, epoch_loss, training_accuracy]) - - train_loop.write( - f"\nAverage training loss: {epoch_loss:.6f}, Train Correct: {train_correct}", - end="\n", - ) - - -# assuming the dataset(images and classes) are already prepared in a folder -train( - images, - classes, - num_epochs, - model, - device, - num_classes=num_classes, - batch_size=batch_size, -) -``` - -
-
- \ -For a more comprehensive overview, head over to the [Demos](https://unify.ai/docs/ivy/demos/index.html) section with more on the [basics](https://unify.ai/docs/ivy/demos/learn_the_basics.html), a few [guides](https://unify.ai/docs/ivy/demos/guides.html) and a wide-ranging set of [examples](https://unify.ai/docs/ivy/demos/examples_and_demos.html) that demonstrate the transpilation of various popular models. We continue to expand on that list, let us know what demos you'd like us to add next 🎯 +For a more comprehensive overview, head over to the [Demos](https://ivy.dev/docs/demos/index.html) section with more on the [basics](https://ivy.dev/docs/demos/learn_the_basics.html), a few [guides](https://ivy.dev/docs/demos/guides.html) and a wide-ranging set of [examples](https://ivy.dev/docs/demos/examples_and_demos.html) that demonstrate the transpilation of various popular models. We continue to expand on that list, let us know what demos you'd like us to add next 🎯 -Let's take a look at how Ivy works both as a transpiler and a framework in a bit more detail to get an idea of why and where to use it. +# How ivy works? -
-Ivy as a transpiler +Let's take a look at how Ivy works as a transpiler in more detail to get an idea of why and where to use it.
-When should I use Ivy as a transpiler? +When is Ivy's transpiler useful? If you want to use building blocks published in other frameworks (neural networks, layers, array computing libraries, training pipelines\...), you want to integrate code developed in various frameworks, or maybe -straight up move code from one framework to another, the transpiler is -definitely the tool 🔧 for the job! As the output of transpilation is -native code in the target framework, you can use the converted code just +straight up migrate code from one framework to another or even between versions of the same framework, the transpiler is +definitely the tool for the job! You can use the converted code just as if it was code originally developed in that framework, applying framework-specific optimizations or tools, instantly exposing your project to all of the unique perks of a different framework.
+\ Ivy\'s transpiler allows you to use code from any other framework (or from any other version of the same framework!) in your own code, by just adding one line of code. Under the hood, Ivy traces a computational -graph and leverages the frontends and backends to link one framework to -another. +graph and leverages the frontends and backends to link one version of one framework to another version of another framework. This way, Ivy makes all ML-related projects available for you, independently of the framework you want to use to research, develop, or @@ -1329,13 +1080,13 @@ deploy systems. Feel free to head over to the docs for the full API reference, but the functions you\'d most likely want to use are: ``` python -# Traces an efficient fully-functional graph from a function, removing all wrapping and redundant code +# Traces an efficient fully-functional graph from a function, removing all wrapping and redundant code. See usage in the documentation ivy.trace_graph() -# Converts framework-specific code to a different framework +# Converts framework-specific code to a target framework of choice. See usage in the documentation ivy.transpile() -# Converts framework-specific code to Ivy +# Converts framework-specific code to Ivy's framework-agnostic API. See usage in the documentation ivy.unify() ``` @@ -1377,212 +1128,48 @@ ret = lazy_graph(x1) If you want to learn more, you can find more information in the [Ivy as a transpiler section of the -docs!](https://unify.ai/docs/ivy/overview/design/ivy_as_a_transpiler.html) - -
- -
-Ivy as a framework - -
-
-When should I use Ivy as a framework? - -As Ivy supports multiple backends, writing code in Ivy breaks you free -from framework limitations. If you want to publish highly flexible code -for everyone to use, independently of the framework they are using, or -you plan to develop ML-related tools and want them to be interoperable -with not only the already existing frameworks, but also with future -frameworks, then Ivy is for you! - -
-
- -The Ivy framework is built on top of various essential components, -mainly the [Backend -Handler](https://unify.ai/docs/ivy/overview/design/building_blocks.html#backend-handler), -which manages what framework is being used behind the scenes and the -[Backend Functional -APIs](https://unify.ai/docs/ivy/overview/design/building_blocks.html#backend-functional-apis), -which provide framework-specific implementations of the Ivy functions. -Likewise, classes such as `ivy.Container` or `ivy.Array` are also -available, facilitating the use of structured data and array-like -objects (learn more about them -[here!](https://unify.ai/docs/ivy/overview/design/ivy_as_a_framework.html)). - -All of the functionalities in Ivy are exposed through the -`Ivy functional API` and the `Ivy stateful API`. All functions in the -[Functional -API](https://unify.ai/docs/ivy/overview/design/building_blocks.html#ivy-functional-api) -are **Framework Agnostic Functions**, which means that we can use them -like this: - -``` python -import ivy -import jax.numpy as jnp -import tensorflow as tf -import numpy as np -import torch - -def mse_loss(y, target): - return ivy.mean((y - target)**2) - -jax_mse = mse_loss(jnp.ones((5,)), jnp.ones((5,))) -tf_mse = mse_loss(tf.ones((5,)), tf.ones((5,))) -np_mse = mse_loss(np.ones((5,)), np.ones((5,))) -torch_mse = mse_loss(torch.ones((5,)), torch.ones((5,))) -``` - -In the example above we show how Ivy\'s functions are compatible with -tensors from different frameworks. This is the same for ALL Ivy -functions. They can accept tensors from any framework and return the -correct result. - -The [Ivy Stateful -API](https://unify.ai/docs/ivy/overview/design/ivy_as_a_framework/ivy_stateful_api.html), -on the other hand, allows you to define trainable modules and layers, -which you can use alone or as a part of any other framework code! - -``` python -import ivy - +docs!](https://ivy.dev/docs/overview/design/ivy_as_a_transpiler.html) -class Regressor(ivy.Module): - def __init__(self, input_dim, output_dim): - self.input_dim = input_dim - self.output_dim = output_dim - super().__init__() - - def _build(self, *args, **kwargs): - self.linear0 = ivy.Linear(self.input_dim, 128) - self.linear1 = ivy.Linear(128, self.output_dim) - - def _forward(self, x): - x = self.linear0(x) - x = ivy.functional.relu(x) - x = self.linear1(x) - return x -``` - -If we put it all together, we\'ll have something like this. This example -uses PyTorch as the backend, but this can easily be changed to your -favorite frameworks, such as TensorFlow, or JAX. - -``` python -import ivy - - -class Regressor(ivy.Module): - def __init__(self, input_dim, output_dim): - self.input_dim = input_dim - self.output_dim = output_dim - super().__init__() - - def _build(self, *args, **kwargs): - self.linear0 = ivy.Linear(self.input_dim, 128) - self.linear1 = ivy.Linear(128, self.output_dim) - - def _forward(self, x): - x = self.linear0(x) - x = ivy.functional.relu(x) - x = self.linear1(x) - return x - -ivy.set_backend('torch') # set backend to PyTorch (or any other backend!) - -model = Regressor(input_dim=1, output_dim=1) -optimizer = ivy.Adam(0.3) - -n_training_examples = 2000 -noise = ivy.random.random_normal(shape=(n_training_examples, 1), mean=0, std=0.1) -x = ivy.linspace(-6, 3, n_training_examples).reshape((n_training_examples, 1)) -y = 0.2 * x ** 2 + 0.5 * x + 0.1 + noise - - -def loss_fn(v, x, target): - pred = model(x, v=v) - return ivy.mean((pred - target) ** 2) - -for epoch in range(40): - # forward pass - pred = model(x) - - # compute loss and gradients - loss, grads = ivy.execute_with_gradients(lambda params: loss_fn(*params), (model.v, x, y)) - - # update parameters - model.v = optimizer.step(model.v, grads) - - # print current loss - print(f'Epoch: {epoch + 1:2d} --- Loss: {ivy.to_numpy(loss).item():.5f}') - -print('Finished training!') -``` - -The model\'s output can be visualized as follows: - -
- -
- -As always, you can find more information about [Ivy as a framework in -the -docs!](https://unify.ai/docs/ivy/overview/design/ivy_as_a_framework.html) - -
- ------------------------------------------------------------------------- # Documentation -You can find Ivy's documentation on the [Docs page](https://unify.ai/docs/ivy/), which includes: -- [Motivation](https://unify.ai/docs/ivy/overview/background.html): This contextualizes the problem Ivy is trying to solve by going over - - The current [ML Explosion](https://unify.ai/docs/ivy/overview/background/ml_explosion.html#ml-explosion). - - Explaining why it is important [to solve this problem](https://unify.ai/docs/ivy/overview/background/why_unify.html#why-unify). - - Explaining how we adhere to existing [standards](https://unify.ai/docs/ivy/overview/background/standardization.html#standardization) to make this happen. -- [Related Work](https://unify.ai/docs/ivy/overview/related_work.html): Which paints a picture of the role Ivy plays in the ML stack, comparing it to other existing solutions in terms of functionalities and abstraction level. -- [Design](https://unify.ai/docs/ivy/overview/design.html): A user-focused guide about the design decision behind the architecture and the main building blocks of Ivy. -- [Deep Dive](https://unify.ai/docs/ivy/overview/deep_dive.html): Which delves deeper into the implementation details of Ivy and is oriented towards potential contributors to the code base. +You can find Ivy's documentation on the [Docs page](https://ivy.dev/docs/), which includes: +- [Motivation](https://ivy.dev/docs/overview/motivation.html): This contextualizes the problem Ivy is trying to solve by going over + - The current [ML Explosion](https://ivy.dev/docs/overview/motivation/ml_explosion.html#ml-explosion). + - Explaining why it is important [to solve this problem](https://ivy.dev/docs/overview/motivation/why_unify.html#why-unify). + - Explaining how we adhere to existing [standards](https://ivy.dev/docs/overview/motivation/standardization.html#standardization) to make this happen. +- [Related Work](https://ivy.dev/docs/overview/related_work.html): Which paints a picture of the role Ivy plays in the ML stack, comparing it to other existing solutions in terms of functionalities and abstraction level. +- [Design](https://ivy.dev/docs/overview/design.html): A user-focused guide about the design decision behind the architecture and the main building blocks of Ivy. +- [Deep Dive](https://ivy.dev/docs/overview/deep_dive.html): Which delves deeper into the implementation details of Ivy and is oriented towards potential contributors to the code base. ------------------------------------------------------------------------- # Contributing We believe that everyone can contribute and make a difference. Whether -it\'s writing code 💻, fixing bugs 🐛, or simply sharing feedback 💬, +it\'s writing code, fixing bugs, or simply sharing feedback, your contributions are definitely welcome and appreciated 🙌 -Check out all of our [Open Tasks](https://unify.ai/docs/ivy/overview/contributing/open_tasks.html), -and find out more info in our [Contributing guide](https://unify.ai/docs/ivy/overview/contributing.html) -in the docs! +Check out all of our [Open Tasks](https://ivy.dev/docs/overview/contributing/open_tasks.html), +and find out more info in our [Contributing guide](https://ivy.dev/docs/overview/contributing.html) +in the docs! Or to immediately dive into a useful task, look for any failing tests on our [Test Dashboard](https://github.com/Transpile-AI/ivy-tests-dashboard/blob/main/DASHBOARD.md)! -Join our amazing community as a [contributor](https://unify.ai/docs/ivy/overview/contributing/volunteer_program.html), and help accelerate our journey to unify all ML frameworks! - - - + + ------------------------------------------------------------------------- # Community -In order to achieve the ambitious goal of unifying AI, we definitely need -as many hands as possible on it! Whether you are a seasoned developer or -just starting out, you\'ll find a place here! Join the Ivy community on -our [Discord](https://discord.gg/sXyFF8tDtm) 👾 server, which is the +Join our growing community on a mission to make conversions between frameworks simple and accessible to all! +Whether you are a seasoned developer or just starting out, you\'ll find a place here! Join the Ivy community on +our [Discord](https://discord.gg/mMnS8Egy) 👾 server, which is the perfect place to ask questions, share ideas, and get help from both -fellow developers and the Ivy Team directly! +fellow developers and the Ivy Team directly. -Also! Feel free to follow us on -[Twitter](https://twitter.com/letsunifyai) 🐦 as well, we use it to -share updates, sneak peeks, and all sorts of relevant news, certainly a -great way to stay in the loop 😄 +See you there! -Can\'t wait to see you there! - ------------------------------------------------------------------------- # Citation