在框架之间转换机器学习代码
Ivy 是一个开源机器学习框架,可以让你:
- 使用
ivy.source_to_source
在框架之间转换 ML 模型、工具和库,同时保持完整功能 - 使用
ivy.trace_graph
在任何原生框架(PyTorch、TensorFlow 等)中创建优化的基于图的模型和函数 - 使用
ivy.transpile
以图追踪方式在任何框架中使用你的 ML 模型或函数
安装 ivy
设置 Ivy 最简单的方法是使用 pip 安装:
pip install ivy
Docker 镜像
你可以从以下地址拉取 Ivy 的 Docker 镜像:
docker pull ivyllc/ivy:latest
从源代码安装
如果你想利用最新的更改,也可以从源代码安装 Ivy,但我们不能确保所有功能都能正常工作 😅
git clone https://github.com/ivy-llc/ivy.git
cd ivy
pip install --user -e .
如果你想设置测试和各种框架,最好查看设置页面,那里提供了特定操作系统和 IDE 的说明和视频教程!
入门
Ivy 的转译器允许你在不同的 ML 框架之间转换代码。查看我们的快速入门笔记本,简要了解其功能!
最重要的笔记本是:
除此之外,根据你想要在哪些框架之间转换代码,在本页面下方还有更多示例 👇,其中包含了在 PyTorch、JAX、TensorFlow 和 NumPy 之间转译的多个模型和库。
使用 ivy
安装 ivy 后,你可以立即开始使用它,例如:
将任何代码从一个框架转译到另一个框架
import ivy
import torch
import jax
def jax_fn(x):
a = jax.numpy.dot(x, x)
b = jax.numpy.mean(x)
返回 x * a + b
jax_x = jax.numpy.array([1., 2., 3.])
torch_x = torch.tensor([1., 2., 3.])
torch_fn = ivy.transpile(jax_fn, source="jax", to="torch", args=(jax_x,))
ret = torch_fn(torch_x)
使用任何后端运行您的代码
import ivy
import torch
import jax
ivy.set_backend("jax")
x = jax.numpy.array([1, 2, 3])
y = jax.numpy.array([3, 2, 1])
z = ivy.add(x, y)
ivy.set_backend('torch')
x = torch.tensor([1, 2, 3])
y = torch.tensor([3, 2, 1])
z = ivy.add(x, y)
示例页面展示了各种演示和教程,展示了Ivy的功能以及多个使用案例,但您也可以在这里查看一些更简短的特定框架示例 ⬇️
我正在使用PyTorch
您可以使用Ivy从以下获取PyTorch代码:任何模型
从TensorFlow
import ivy import torch import tensorflow as tf # 获取预训练的keras模型 eff_encoder = tf.keras.applications.efficientnet_v2.EfficientNetV2B0( include_top=False, weights="imagenet", input_shape=(224, 224, 3) ) # 将其转换为带有相应参数的torch.nn.Module noise = tf.random.normal(shape=(1, 224, 224, 3)) torch_eff_encoder = ivy.transpile(eff_encoder, source="tensorflow", to="torch", args=(noise,)) # 使用转换后的编码器构建分类器 class Classifier(torch.nn.Module): def __init__(self, num_classes=20): super().__init__() self.encoder = torch_eff_encoder self.fc = torch.nn.Linear(1280, num_classes) def forward(self, x): x = self.encoder(x) return self.fc(x) # 初始化一个可训练的、可自定义的torch.nn.Module classifier = Classifier() ret = classifier(torch.rand((1, 244, 244, 3)))
从JAX
import ivy import jax import torch # 获取预训练的haiku模型 # https://github.com/unifyai/demos/blob/15c235f/scripts/deepmind_perceiver_io.py from deepmind_perceiver_io import key, perceiver_backbone # 将其转换为带有相应参数的torch.nn.Module dummy_input = jax.random.uniform(key, shape=(1, 3, 224, 224)) params = perceiver_backbone.init(rng=key, images=dummy_input) ivy.set_backend("jax") backbone = ivy.transpile( perceiver_backbone, source="jax", to="torch", params_v=params, kwargs={"images": dummy_input} ) # 使用转换后的backbone构建分类器 class PerceiverIOClassifier(torch.nn.Module): def __init__(self, num_classes=20): super().__init__() self.backbone = backbone self.max_pool = torch.nn.MaxPool2d((512, 1)) self.flatten = torch.nn.Flatten() self.fc = torch.nn.Linear(1024, num_classes) def forward(self, x): x = self.backbone(images=x) x = self.flatten(self.max_pool(x)) return self.fc(x) # 初始化一个可训练的、可自定义的torch.nn.Module classifier = PerceiverIOClassifier() ret = classifier(torch.rand((1, 3, 224, 224)))
任何库
从Tensorflow
import ivy import torch import os os.environ["SM_FRAMEWORK"] = "tf.keras" import segmentation_models as sm # 将sm从tensorflow转换为torch torch_sm = ivy.transpile(sm, source="tensorflow", to="torch") # 获取一些类似图像的数组 output = torch.rand((1, 3, 512, 512)) target = torch.rand((1, 3, 512, 512)) # 使用库中任何函数的转换版本! out = torch_sm.metrics.iou_score(output, target)
从JAX
import ivy import rax import torch # 将rax从jax转换为torch torch_rax = ivy.transpile(rax, source="jax", to="torch") # 获取一些数组 scores = torch.tensor([2.2, 1.3, 5.4]) labels = torch.tensor([1.0, 0.0, 0.0]) # 使用库中任何函数的转换版本! out = torch_rax.poly1_softmax_loss(scores, labels)
从NumPy
import ivy import torch import madmom # 将madmom从numpy转换为torch torch_madmom = ivy.transpile(madmom, source="numpy", to="torch") # 获取一些数组 freqs = torch.arange(20) * 10 # 使用库中任何函数的转换版本! out = torch_madmom.audio.filters.hz2midi(freqs)
任何函数
从Tensorflow
import ivy import tensorflow as tf import torch def loss(predictions, targets): return tf.sqrt(tf.reduce_mean(tf.square(predictions - targets))) # 将任何函数从tf转换为torch torch_loss = ivy.transpile(loss, source="tensorflow", to="torch") # 获取一些数组 p = torch.tensor([3.0, 2.0, 1.0]) t = torch.tensor([0.0, 0.0, 0.0]) # 使用转换后的版本! out = torch_loss(p, t)
从JAX
import ivy import jax.numpy as jnp import torch def loss(predictions, targets): return jnp.sqrt(jnp.mean((predictions - targets) ** 2)) # 将任何函数从jax转换为torch torch_loss = ivy.transpile(loss, source="jax", to="torch") # 获取一些数组 p = torch.tensor([3.0, 2.0, 1.0]) t = torch.tensor([0.0, 0.0, 0.0]) # 使用转换后的版本! out = torch_loss(p, t)
从NumPy
import ivy import numpy as np import torch def loss(predictions, targets): return np.sqrt(np.mean((predictions - targets) ** 2)) # 将任何函数从numpy转换为torch torch_loss = ivy.transpile(loss, source="numpy", to="torch") # 获取一些数组 p = torch.tensor([3.0, 2.0, 1.0]) t = torch.tensor([0.0, 0.0, 0.0]) # 使用转换后的版本! out = torch_loss(p, t)
我正在使用TensorFlow
您可以使用Ivy从以下获取TensorFlow代码:任何模型
从PyTorch
import ivy import torch import timm import tensorflow as tf # 获取预训练的pytorch模型 mlp_encoder = timm.create_model("mixer_b16_224", pretrained=True, num_classes=0) # 将其转换为带有相应参数的keras.Model noise = torch.randn(1, 3, 224, 224) mlp_encoder = ivy.transpile(mlp_encoder, to="tensorflow", args=(noise,)) # 使用转换后的编码器构建分类器 class Classifier(tf.keras.Model): def __init__(self): super().__init__() self.encoder = mlp_encoder self.output_dense = tf.keras.layers.Dense(units=1000, activation="softmax") def call(self, x): x = self.encoder(x) return self.output_dense(x) # 将分类器转换并将其用作标准的keras.Model x = tf.random.normal(shape=(1, 3, 224, 224)) model = Classifier() ret = model(x)
从JAX
import ivy import jax import tensorflow as tf # 获取一个预训练的haiku模型 # https://ivy.dev/demos/scripts/deepmind_perceiver_io.py from deepmind_perceiver_io import key, perceiver_backbone # 将其转译为具有相应参数的tf.keras.Model dummy_input = jax.random.uniform(key, shape=(1, 3, 224, 224)) params = perceiver_backbone.init(rng=key, images=dummy_input) backbone = ivy.transpile( perceiver_backbone, to="tensorflow", params_v=params, args=(dummy_input,) ) # 使用转译后的backbone构建分类器 class PerceiverIOClassifier(tf.keras.Model): def __init__(self, num_classes=20): super().__init__() self.backbone = backbone self.max_pool = tf.keras.layers.MaxPooling1D(pool_size=512) self.flatten = tf.keras.layers.Flatten() self.fc = tf.keras.layers.Dense(num_classes) def call(self, x): x = self.backbone(x) x = self.flatten(self.max_pool(x)) return self.fc(x) # 初始化一个可训练的、可自定义的tf.keras.Model x = tf.random.normal(shape=(1, 3, 224, 224)) classifier = PerceiverIOClassifier() ret = classifier(x)
任意库
从PyTorch
import ivy import kornia import requests import numpy as np import jax import jax.numpy as jnp from PIL import Image # 将kornia从torch转译为jax jax_kornia = ivy.transpile(kornia, source="torch", to="jax") # 获取一张图片 url = "http://images.cocodataset.org/train2017/000000000034.jpg" raw_img = Image.open(requests.get(url, stream=True).raw) # 将其转换为kornia预期的格式 img = np.array(raw_img) img = jnp.transpose(jnp.array(img), (2, 0, 1)) img = jnp.expand_dims(img, 0) / 255 # 使用库中任何函数的转译版本! out = jax_kornia.enhance.sharpness(img, 5)
从TensorFlow
import ivy import tensorflow_probability as tfp import jax # 将tensorflow_probability从tensorflow转译为jax jax_tfp = ivy.transpile(tfp, source="tensorflow", to="jax") # 获取一些数组 key = jax.random.PRNGKey(0) x = jax.random.normal(key, (100,)) # 使用库中任何函数的转译版本! out = jax_tfp.stats.percentile(x, 50.0)
从NumPy
import ivy import madmom import jax import jax.numpy as jnp # 将madmom从numpy转译为jax jax_madmom = ivy.transpile(madmom, source="numpy", to="jax") # 获取一些数组 freqs = jnp.arange(20) * 10 # 使用库中任何函数的转译版本! out = jax_madmom.audio.filters.hz2midi(freqs)
任意函数
从PyTorch
import ivy import torch import jax import jax.numpy as jnp def loss(predictions, targets): return torch.sqrt(torch.mean((predictions - targets) ** 2)) # 将任何函数从torch转译为jax jax_loss = ivy.transpile(loss, source="torch", to="jax") # 获取一些数组 key = jax.random.PRNGKey(0) p = jax.random.uniform(key, (3,)) t = jnp.zeros((3,)) # 使用转译后的版本! out = jax_loss(p, t)
从TensorFlow
import ivy import tensorflow as tf import jax import jax.numpy as jnp def loss(predictions, targets): return tf.sqrt(tf.reduce_mean((predictions - targets) ** 2)) # 将任何函数从tensorflow转译为jax jax_loss = ivy.transpile(loss, source="tensorflow", to="jax") # 获取一些数组 key = jax.random.PRNGKey(0) p = jax.random.uniform(key, (3,)) t = jnp.zeros((3,)) # 使用转译后的版本! out = jax_loss(p, t)
从NumPy
import ivy import numpy as np import jax import jax.numpy as jnp def loss(predictions, targets): return np.sqrt(np.mean((predictions - targets) ** 2)) # 将任何函数从numpy转译为jax jax_loss = ivy.transpile(loss, source="numpy", to="jax") # 获取一些数组 key = jax.random.PRNGKey(0) p = jax.random.uniform(key, (3,)) t = jnp.zeros((3,)) # 使用转译后的版本! out = jax_loss(p, t)
我使用NumPy
你可以使用Ivy从以下来源获取NumPy代码:任意模型
从PyTorch
import ivy import timm import torch import numpy as np # 获取一个预训练的pytorch模型 mlp_encoder = timm.create_model("mixer_b16_224", pretrained=True, num_classes=0) # 将其转译为一个具有相应参数的NumPy函数 noise = torch.randn(1, 3, 224, 224) np_mlp_encoder = ivy.transpile(mlp_encoder, source="torch", to="numpy", args=(noise,)) # 使用转译后的编码器构建一个分类器 def Classifier(x, num_classes=1000): x = np_mlp_encoder(x) fc = np.random.randn(x.shape[-1], num_classes) return np.dot(x, fc) # 将分类器用作标准的NumPy函数 x = np.random.randn(1, 3, 224, 224) ret = Classifier(x)
从TensorFlow
import ivy import numpy as np import tensorflow as tf # 获取一个预训练的keras模型 eff_encoder = tf.keras.applications.efficientnet_v2.EfficientNetV2B0( include_top=False, weights="imagenet", input_shape=(224, 224, 3) ) # 将其转译为一个具有相应参数的NumPy函数 noise = tf.random.normal(shape=(1, 224, 224, 3)) np_eff_encoder = ivy.transpile(eff_encoder, source="tensorflow", to="numpy", args=(noise,)) # 使用转译后的编码器构建一个分类器 def Classifier(x, num_classes=1000): x = np_eff_encoder(x) fc = np.random.randn(x.shape[-1], num_classes) return np.dot(x, fc) # 将分类器用作标准的NumPy函数 x = np.random.randn(1, 224, 224, 3) ret = Classifier(x)
从JAX
import ivy import jax import numpy as np # 获取一个预训练的haiku模型 # https://ivy.dev/demos/scripts/deepmind_perceiver_io.py from deepmind_perceiver_io import key, perceiver_backbone # 将其转译为一个具有相应参数的NumPy函数 dummy_input = jax.random.uniform(key, shape=(1, 3, 224, 224)) params = perceiver_backbone.init(rng=key, images=dummy_input) np_backbone = ivy.transpile( perceiver_backbone, to="numpy", params_v=params, args=(dummy_input,) ) # 使用转译后的backbone构建一个分类器 def Classifier(x, num_classes=20): x = np_backbone(x) x = np.max(x, axis=1) x = x.flatten() fc = np.random.randn(x.shape[-1], num_classes) return np.dot(x, fc) # 将分类器用作标准的NumPy函数 x = np.random.randn(1, 3, 224, 224) ret = Classifier(x)
任意库
从PyTorch
import ivy import kornia import requests import numpy as np from PIL import Image # 将kornia从torch转译为numpy np_kornia = ivy.transpile(kornia, source="torch", to="numpy") # 获取一张图片 url = "http://images.cocodataset.org/train2017/000000000034.jpg" raw_img = Image.open(requests.get(url, stream=True).raw) # 将其转换为kornia预期的格式 img = np.array(raw_img) img = np.transpose(img, (2, 0, 1)) img = np.expand_dims(img, 0) / 255 # 使用库中任何函数的转译版本! out = np_kornia.enhance.sharpness(img, 5)
从TensorFlow
import ivy import tensorflow_probability as tfp import numpy as np # 将tensorflow_probability从tensorflow转译为numpy np_tfp = ivy.transpile(tfp, source="tensorflow", to="numpy") # 获取一些数组 x = np.random.randn(100) # 使用库中任何函数的转译版本! out = np_tfp.stats.percentile(x, 50.0)
从JAX
import ivy import rax import numpy as np # 将rax从jax转译为numpy np_rax = ivy.transpile(rax, source="jax", to="numpy") # 获取一些数组 scores = np.array([2.2, 1.3, 5.4]) labels = np.array([1.0, 0.0, 0.0]) # 使用库中任何函数的转译版本! out = np_rax.poly1_softmax_loss(scores, labels)
任意函数
从PyTorch
import ivy import torch import numpy as np def loss(predictions, targets): return torch.sqrt(torch.mean((predictions - targets) ** 2)) # 将任何函数从torch转译为numpy np_loss = ivy.transpile(loss, source="torch", to="numpy") # 获取一些数组 p = np.array([3.0, 2.0, 1.0]) t = np.array([0.0, 0.0, 0.0]) # 使用转译后的版本! out = np_loss(p, t)
从TensorFlow
import ivy import tensorflow as tf import numpy as np def loss(predictions, targets): return tf.sqrt(tf.reduce_mean((predictions - targets) ** 2)) # 将任何函数从tensorflow转译为numpy np_loss = ivy.transpile(loss, source="tensorflow", to="numpy") # 获取一些数组 p = np.array([3.0, 2.0, 1.0]) t = np.array([0.0, 0.0, 0.0]) # 使用转译后的版本! out = np_loss(p, t)
从JAX
import ivy import jax.numpy as jnp import numpy as np def loss(predictions, targets): return jnp.sqrt(jnp.mean((predictions - targets) ** 2)) # 将任何函数从jax转译为numpy np_loss = ivy.transpile(loss, source="jax", to="numpy") # 获取一些数组 p = np.array([3.0, 2.0, 1.0]) t = np.array([0.0, 0.0, 0.0]) # 使用转译后的版本! out = np_loss(p, t)
将kornia从torch转译为jax
jax_kornia = ivy.transpile(kornia, source="torch", to="jax")
获取一张图像
url = "http://images.cocodataset.org/train2017/000000000034.jpg" raw_img = Image.open(requests.get(url, stream=True).raw)
将其转换为kornia期望的格式
img = jnp.transpose(jnp.array(raw_img), (2, 0, 1)) img = jnp.expand_dims(img, 0) / 255
使用库中任何函数的转译版本!
out = jax_kornia.enhance.sharpness(img, 5)
</details>
<details>
<summary>从TensorFlow</summary>
``` python
import ivy
import jax
import os
os.environ["SM_FRAMEWORK"] = "tf.keras"
import segmentation_models as sm
# 将sm从tensorflow转译为jax
jax_sm = ivy.transpile(sm, source="tensorflow", to="jax")
# 获取一些类似图像的数组
key = jax.random.PRNGKey(23)
key1, key2 = jax.random.split(key)
output = jax.random.uniform(key1, (1, 3, 512, 512))
target = jax.random.uniform(key2, (1, 3, 512, 512))
# 使用库中任何函数的转译版本!
out = jax_sm.metrics.iou_score(output, target)
从NumPy
import ivy
import madmom
import jax.numpy as jnp
# 将madmom从numpy转译为jax
jax_madmom = ivy.transpile(madmom, source="numpy", to="jax")
# 获取一些数组
freqs = jnp.arange(20) * 10
# 使用库中任何函数的转译版本!
out = jax_madmom.audio.filters.hz2midi(freqs)
任何函数
从PyTorch
import ivy import torch import jax.numpy as jnp def loss(predictions, targets): return torch.sqrt(torch.mean((predictions - targets) ** 2)) # 将任何函数从torch转译为jax jax_loss = ivy.transpile(loss, source="torch", to="jax") # 获取一些数组 p = jnp.array([3.0, 2.0, 1.0]) t = jnp.array([0.0, 0.0, 0.0]) # 使用转译版本! out = jax_loss(p, t)
从TensorFlow
import ivy import tensorflow as tf import jax.numpy as jnp def loss(predictions, targets): return tf.sqrt(tf.reduce_mean(tf.square(predictions - targets))) # 将任何函数从tf转译为jax jax_loss = ivy.transpile(loss, source="tensorflow", to="jax") # 获取一些数组 p = jnp.array([3.0, 2.0, 1.0]) t = jnp.array([0.0, 0.0, 0.0]) # 使用转译版本! out = jax_loss(p, t)
从NumPy
import ivy import numpy as np import jax import jax.numpy as jnp jax.config.update('jax_enable_x64', True) def loss(predictions, targets): return np.sqrt(np.mean((predictions - targets) ** 2)) # 将任何函数从numpy转译为jax jax_loss = ivy.transpile(loss, source="numpy", to="jax") # 获取一些数组 p = jnp.array([3.0, 2.0, 1.0]) t = jnp.array([0.0, 0.0, 0.0]) # 使用转译版本! out = jax_loss(p, t)
我正在使用NumPy
您可以使用Ivy从以下获取NumPy代码:任何库
从PyTorch
import ivy import kornia import requests import numpy as np from PIL import Image # 将kornia从torch转译为np np_kornia = ivy.transpile(kornia, source="torch", to="numpy") # 获取一张图像 url = "http://images.cocodataset.org/train2017/000000000034.jpg" raw_img = Image.open(requests.get(url, stream=True).raw) # 将其转换为kornia期望的格式 img = np.transpose(np.array(raw_img), (2, 0, 1)) img = np.expand_dims(img, 0) / 255 # 使用库中任何函数的转译版本! out = np_kornia.enhance.sharpness(img, 5)
从TensorFlow
import ivy import numpy as np import os os.environ["SM_FRAMEWORK"] = "tf.keras" import segmentation_models as sm # 将sm从tensorflow转译为numpy np_sm = ivy.transpile(sm, source="tensorflow", to="numpy") # 获取一些类似图像的数组 output = np.random.rand(1, 3, 512, 512).astype(dtype=np.float32) target = np.random.rand(1, 3, 512, 512).astype(dtype=np.float32) # 使用库中任何函数的转译版本! out = np_sm.metrics.iou_score(output, target)
从Jax
import ivy import rax import numpy as np # 将rax从jax转译为numpy np_rax = ivy.transpile(rax, source="jax", to="numpy") # 获取一些数组 scores = np.array([2.2, 1.3, 5.4]) labels = np.array([1.0, 0.0, 0.0]) # 使用库中任何函数的转译版本! out = np_rax.poly1_softmax_loss(scores, labels)
任何函数
从PyTorch
import ivy import torch import numpy as np def loss(predictions, targets): return torch.sqrt(torch.mean((predictions - targets) ** 2)) # 将任何函数从torch转译为numpy np_loss = ivy.transpile(loss, source="torch", to="numpy") # 获取一些数组 p = np.array([3.0, 2.0, 1.0]) t = np.array([0.0, 0.0, 0.0]) # 使用转译版本! out = np_loss(p, t)
从TensorFlow
import ivy import tensorflow as tf import numpy as np def loss(predictions, targets): return tf.sqrt(tf.reduce_mean(tf.square(predictions - targets))) # 将任何函数从tf转译为numpy np_loss = ivy.transpile(loss, source="tensorflow", to="numpy") # 获取一些数组 p = np.array([3.0, 2.0, 1.0]) t = np.array([0.0, 0.0, 0.0]) # 使用转译版本! out = np_loss(p, t)
从JAX
import ivy import jax.numpy as jnp import numpy as np def loss(predictions, targets): return jnp.sqrt(jnp.mean((predictions - targets) ** 2)) # 将任何函数从jax转译为numpy np_loss = ivy.transpile(loss, source="jax", to="numpy") # 获取一些数组 p = np.array([3.0, 2.0, 1.0]) t = np.array([0.0, 0.0, 0.0]) # 使用转译版本! out = np_loss(p, t)
Ivy 如何工作?
让我们更详细地看看 Ivy 作为转译器是如何工作的,以了解为什么以及在哪里使用它。
Ivy 的转译器在什么时候有用?
如果您想使用其他框架发布的构建块(神经网络、层、数组计算库、训练流程等),想要集成在各种框架中开发的代码,或者甚至直接将代码从一个框架迁移到另一个框架,或者在同一框架的不同版本之间迁移,转译器绝对是最适合的工具!您可以像使用原本在该框架中开发的代码一样使用转换后的代码,应用特定框架的优化或工具,立即让您的项目享受到不同框架的所有独特优势。
Ivy 的转译器允许您通过只添加一行代码就在自己的代码中使用来自任何其他框架(或同一框架的任何其他版本!)的代码。在底层,Ivy 追踪计算图并利用前端和后端将一个框架的一个版本链接到另一个框架的另一个版本。
这样,Ivy 使所有与 ML 相关的项目都可供您使用,无论您想用哪个框架来研究、开发或部署系统。请随时查看文档以获取完整的 API 参考,但您最可能想要使用的函数是:
# 从函数追踪一个高效的全功能图,移除所有封装和冗余代码。在文档中查看用法
ivy.trace_graph()
# 将特定框架的代码转换为选择的目标框架。在文档中查看用法
ivy.transpile()
# 将特定框架的代码转换为 Ivy 的框架无关 API。在文档中查看用法
ivy.unify()
这些函数可以急切地或惰性地使用。如果您传递了函数追踪所需的参数,图追踪/转译步骤将立即(急切地)发生。否则,图追踪/转译将仅在首次调用返回的函数时发生。
import ivy
import jax
ivy.set_backend("jax")
# 简单的 JAX 函数用于转译
def test_fn(x):
return jax.numpy.sum(x)
x1 = ivy.array([1., 2.])
# 参数可用 -> 转译急切发生
eager_graph = ivy.transpile(test_fn, source="jax", to="torch", args=(x1,))
# eager_graph 现在是 torch 代码并高效运行
ret = eager_graph(x1)
# 参数不可用 -> 转译惰性发生
lazy_graph = ivy.transpile(test_fn, source="jax", to="torch")
# 转译图已初始化,转译将在这里发生
ret = lazy_graph(x1)
# lazy_graph 现在是 torch 代码并高效运行
ret = lazy_graph(x1)
如果您想了解更多,可以在文档的 Ivy 作为转译器部分找到更多信息!
文档
您可以在文档页面找到 Ivy 的文档,其中包括:
- 动机:这通过以下方面来contextualize Ivy 试图解决的问题
- 相关工作:描绘了 Ivy 在 ML 堆栈中的角色,从功能和抽象级别上与其他现有解决方案进行比较。
- 设计:关于架构背后的设计决策和 Ivy 主要构建块的面向用户的指南。
- 深入探讨:更深入地探讨 Ivy 的实现细节,面向潜在的代码库贡献者。
贡献
我们相信每个人都可以贡献并产生影响。无论是编写代码、修复错误,还是仅仅分享反馈,您的贡献都是受欢迎和被赞赏的 🙌
查看我们所有的开放任务,并在文档中的贡献指南中了解更多信息!或者立即投入到有用的任务中,查看我们的测试仪表板上的任何失败测试!
社区
加入我们不断壮大的社区,我们的使命是让框架之间的转换变得简单并对所有人开放!无论您是经验丰富的开发者还是刚刚起步,您都能在这里找到自己的位置!加入 Ivy 社区的 Discord 👾 服务器,这是一个提问、分享想法以及直接从 Ivy 团队和其他开发者那里获得帮助的完美场所。
我们那里见!
引用
如果您在工作中使用了 Ivy,请不要忘记通过在您的参考文献中包含随附的论文 📄 来给予适当的信用。这是表示感谢并帮助继续支持这个和其他开源项目的一种小方式 🙌
@article{lenton2021ivy,
title={Ivy: Templated deep learning for inter-framework portability},
author={Lenton, Daniel and Pardo, Fabio and Falck, Fabian and James, Stephen and Clark, Ronald},
journal={arXiv preprint arXiv:2102.02886},
year={2021}
}