3个不稳定版本
新 0.3.1 | 2024年8月13日 |
---|---|
0.3.0 | 2024年8月10日 |
0.2.0 | 2024年7月30日 |
127 in 数学
每月365次下载
1MB
22K SLoC
包含 (Mach-o exe, 330KB) vendored/qbe/qbe, (Mach-o exe, 84KB) vendored/qbe/parse.o, (Mach-o exe, 41KB) vendored/qbe/amd64/emit.o, (Mach-o exe, 40KB) vendored/qbe/amd64/isel.o, (Mach-o exe, 41KB) vendored/qbe/amd64/sysv.o, (Mach-o exe, 46KB) vendored/qbe/arm64/abi.o 等23个更多.
普通的函数
jyafn
是一个项目,通过使用编译为机器码的计算图,使用方便且熟悉的Python界面来启用MLOps。
💡 不要忘记查看文档以获取更深入的信息。

看看这个小巧可爱的代码片段
import jyafn as fn
import numpy as np
@fn.func
def reduce_sum(mat: fn.tensor[2, 2]) -> fn.scalar:
return np.sum(mat)
我知道:它看起来有点奇怪,但如果我告诉你
- 它可以编译成机器码。
- 你仍然可以像调用普通Python函数一样调用它。
- 你可以将其导出、加载并在Go(或Rust、或Python、或C!)中调用它
很酷,对吧?这基本上是tf.function
+ onnx
在一个包中!
一个快速示例
让我们在jyafn
中编写一个愚蠢的函数
@fn.func
def a_fun(a: fn.scalar, b: fn.scalar) -> fn.scalar:
return 2.0 * a + b + 1.0
它如此愚蠢,以至于如果你像通常那样调用它,a_fun(2, 3)
,你会得到你预期的,8
。但这不是有趣的。有趣的在于你可以将此函数导出到一个文件
with open("a_fun.jyafn", "wb") as f:
f.write(a_fun.dump())
现在你可以在任何地方传递这个文件,它都会正常工作。例如,让我们从Go调用它
// Read exported data:
code, err := os.ReadFile("a_fun.jyafn")
if err != nil {
log.Fatal(err)
}
// Load the function:
fn, err := jyafn.LoadFunction(code)
if err != nil {
log.Fatal(err)
}
// Call the function:
result, err := jyafn.Call[float64](
fn,
struct {
a float64
b float64
}{a: 2.0, b: 3.0},
)
if err != nil {
log.Fatal(err)
}
fmt.Println(result, "==", 8.0)
如何使用它
在所有情况下,很遗憾,您需要安装GNU的binutils
(或等效版本),因为我们需要汇编器和链接器来完成QBE的任务(这不是构建依赖项!)。在大多数计算机上,它很可能已经安装(作为gcc
或Python的一部分)。然而,当您例如构建Docker镜像时,这是一个需要了解的细节。此外,jyafn
在Windows上保证无法工作。有关您的特定编程环境,请参阅下文
Python
从PyPI获取软件包
这是获取jyafn
的最便捷方式
pip install jyafn
从源代码构建
克隆仓库,然后
make install
这应该可以解决问题。您可以像这样设置特定的Python版本
make install py=3.12
目前默认版本是3.11。
目前,Python版本取决于Rust编译器才能工作。它将从源代码编译jyafn
。因此,您需要Rust的包管理器cargo
,以及用于从Rust代码构建Python包的工具maturin
。Maturin可以用pip
轻松安装
pip install maturin
Go
您可以用它作为Go模块
import "github.com/viodotcom/jyafn/jyafn-go/pkg/jyafn"
您还需要在您的系统中安装libjyafn
共享对象,该对象可在GitHub的最新发布中找到。
Rust
您可以直接从crates.io获取jyafn
crate的最新版本,这是本项目的基础
cargo add jyafn
C
Jyafn可通过GitHub最新发布中提供的libjyafn
共享对象直接从C使用。请查看Rust接口以获取有关如何使用可用函数的详细信息。
常见问题解答
出了一些问题!
是的,肯定有问题。您看到的是基本上是一个小型的JIT(即时编译器)。您的Python指令(添加这个!乘以那个!)被记录在一个计算图中,然后通过QBE编译成机器代码,QBE做所有的重活,“编译”事情。这段代码作为运行程序中的函数指针暴露出来。
加载任意代码不是安全问题吗?
是的,但jyafn
产生的代码绝对不是任意的。首先,它是纯的:它不会导致任何外部突变。其次,由于它基于有向无环图(acyclic computational graph),因此可以保证完成(代码的大小限制了运行时间)。第三,没有交换机器代码:该代码仅在所在进程的持续时间内有效。交换的是计算图,而不是代码。
所以,我可以在里面写任何东西,它都会工作?
绝对不是
- 您的Python函数只能有常量大小的循环。
- 您使用的库必须能够处理泛型Python对象(即支持魔术方法,如
__add__
、__sub__
等...)。幸运的是,numpy
正是这样对其ndarray
做。 if-else
仍然有点问题(您可以用choose
方法代替)。如果有需求,将来可以解决这个问题。- 到目前为止,支持主要集中在DS使用上。因此,浮点数和布尔值是支持的,但其他原始类型则不支持。
- 偶尔,在众多功能中可能会出现一个不支持的新功能。然而,实现它非常简单。
它比纯Python快吗?
当然!在 ./jyafn-python/tests/simple_graph.py
中有一个基准测试,您可以查看。有一个示例显示比普通的CPython快10倍。
支持哪些编程语言?
到目前为止,支持Go、Rust、Python和C。您可以使用 cjyafn
库将 jyafn
移植到您的语言。该仓库的GitHub发布版中提供了编译后的共享对象。
项目的当前状态如何?
它已经足够成熟可以进行测试。需要实验小白鼠!
依赖项
~17-28MB
~486K SLoC