「TVM教程」创建 Relax

TVM Relax抽象层:动态深度学习模型编译与部署新范式 深度学习编译器是连接算法模型与硬件执行的关键桥梁,其核心在于将高级框架描述的计算图转换为高效的底层代码。传统静态编译方案在处理动态形状、可变输入和控制流时面临挑战,这推动了支持动态性的中间表示设计。TVM Relax抽象层通过引入符号形状、动态类型系统和交互式编译流程,为动态模型提供了原生支持,显著提升了编译灵活性和开发体验。该技术特别适用于自然语言处理中可变序列长度、动态路由网络等场景,通过call_tir机制将高层图优化与底层性能调优解耦,实现了从动态图描述到高性能硬件代码的端到端编译。Relax与Re 阅读详情

TVM 现已更新到 0.21.0 版本,TVM 中文文档已经和新版本对齐。

Apache TVM 是一个深度的深度学习编译框架,适用于 CPU、GPU 和各种机器学习加速芯片。

在线运行 TVM 学习教程→go.hyper.ai/PEh1Q

本教程演示了如何创建 Relax 函数和程序。我们将介绍使用 TVMScript 和 Relax NNModule API 定义 Relax 函数的各种方式。

使用 TVMScript 创建 Relax 程序

TVMScript 是一个用于表示 Apache TVM 中间表示(IR)的领域特定语言(DSL)。它是 Python 的一种变体,可用于定义一个包含 TensorIR 和 Relax 函数的 IRModule。

在本节中,我们将展示如何使用 TVMScript 定义一个仅使用高级 Relax 运算符的简单 MLP 模型。

from tvm import relax, topi
from tvm.script import ir as I
from tvm.script import relax as R
from tvm.script import tir as T


@I.ir_module
class RelaxModule:
    @R.function
    def forward(
        data: R.Tensor(("n", 784), dtype="float32"),
        w0: R.Tensor((128, 784), dtype="float32"),
        b0: R.Tensor((128,), dtype="float32"),
        w1: R.Tensor((10, 128), dtype="float32"),
        b1: R.Tensor((10,), dtype="float32"),
    ) -> R.Tensor(("n", 10), dtype="float32"):
        with R.dataflow():
            lv0 = R.matmul(data, R.permute_dims(w0)) + b0
            lv1 = R.nn.relu(lv0)
            lv2 = R.matmul(lv1, R.permute_dims(w1)) + b1
            R.output(lv2)
        return lv2


RelaxModule.show()

输出:

# from tvm.script import ir as I
# from tvm.script import tir as T
# from tvm.script import relax as R

@I.ir_module
class Module:
    @R.function
    def forward(data: R.Tensor(("n", 784), dtype="float32"), w0: R.Tensor((128, 784), dtype="float32"), b0: R.Tensor((128,), dtype="float32"), w1: R.Tensor((10, 128), dtype="float32"), b1: R.Tensor((10,), dtype="float32")) -> R.Tensor(("n", 10), dtype="float32"):
        n = T.int64()
        with R.dataflow():
            lv: R.Tensor((784, 128), dtype="float32") = R.permute_dims(w0, axes=None)
            lv1: R.Tensor((n, 128), dtype="float32") = R.matmul(data, lv, out_dtype="void")
            lv0: R.Tensor((n, 128), dtype="float32") = R.add(lv1, b0)
            lv1_1: R.Tensor((n, 128), dtype="float32") = R.nn.relu(lv0)
            lv4: R.Tensor((128, 10), dtype="float32") = R.permute_dims(w1, axes=None)
            lv5: R.Tensor((n, 10), dtype="float32") = R.matmul(lv1_1, lv4, out_dtype="void")
            lv2: R.Tensor((n, 10), dtype="float32") = R.add(lv5, b1)
            R.output(lv2)
        return lv2

Relax 不仅是图层级的中间表示(IR),还支持跨层级的表示与转换。具体来说,我们可以在 Relax 函数中直接调用 TensorIR 函数。

@I.ir_module
class RelaxModuleWithTIR:
    @T.prim_func
    def relu(x: T.handle, y: T.handle):
        n, m = T.int64(), T.int64()
        X = T.match_buffer(x, (n, m), "float32")
        Y = T.match_buffer(y, (n, m), "float32")
        for i, j in T.grid(n, m):
            with T.block("relu"):
                vi, vj = T.axis.remap("SS", [i, j])
                Y[vi, vj] = T.max(X[vi, vj], T.float32(0))

    @R.function
    def forward(
        data: R.Tensor(("n", 784), dtype="float32"),
        w0: R.Tensor((128, 784), dtype="float32"),
        b0: R.Tensor((128,), dtype="float32"),
        w1: R.Tensor((10, 128), dtype="float32"),
        b1: R.Tensor((10,), dtype="float32"),
    ) -> R.Tensor(("n", 10), dtype="float32"):
        n = T.int64()
        cls = RelaxModuleWithTIR
        with R.dataflow():
            lv0 = R.matmul(data, R.permute_dims(w0)) + b0
            lv1 = R.call_tir(cls.relu, lv0, R.Tensor((n, 128), dtype="float32"))
            lv2 = R.matmul(lv1, R.permute_dims(w1)) + b1
            R.output(lv2)
        return lv2


RelaxModuleWithTIR.show()

输出:

# from tvm.script import ir as I
# from tvm.script import tir as T
# from tvm.script import relax as R

@I.ir_module
class Module:
    @T.prim_func
    def relu(x: T.handle, y: T.handle):
        n, m = T.int64(), T.int64()
        X = T.match_buffer(x, (n, m))
        Y = T.match_buffer(y, (n, m))
        # with T.block("root"):
        for i, j in T.grid(n, m):
            with T.block("relu"):
                vi, vj = T.axis.remap("SS", [i, j])
                T.reads(X[vi, vj])
                T.writes(Y[vi, vj])
                Y[vi, vj] = T.max(X[vi, vj], T.float32(0.0))

    @R.function
    def forward(data: R.Tensor(("n", 784), dtype="float32"), w0: R.Tensor((128, 784), dtype="float32"), b0: R.Tensor((128,), dtype="float32"), w1: R.Tensor((10, 128), dtype="float32"), b1: R.Tensor((10,), dtype="float32")) -> R.Tensor(("n", 10), dtype="float32"):
        n = T.int64()
        cls = Module
        with R.dataflow():
            lv: R.Tensor((784, 128), dtype="float32") = R.permute_dims(w0, axes=None)
            lv1: R.Tensor((n, 128), dtype="float32") = R.matmul(data, lv, out_dtype="void")
            lv0: R.Tensor((n, 128), dtype="float32") = R.add(lv1, b0)
            lv1_1 = R.call_tir(cls.relu, (lv0,), out_sinfo=R.Tensor((n, 128), dtype="float32"))
            lv4: R.Tensor((128, 10), dtype="float32") = R.permute_dims(w1, axes=None)
            lv5: R.Tensor((n, 10), dtype="float32") = R.matmul(lv1_1, lv4, out_dtype="void")
            lv2: R.Tensor((n, 10), dtype="float32") = R.add(lv5, b1)
            R.output(lv2)
        return lv2

备注

你可能会注意到:打印输出的内容与我们编写的 TVMScript 代码不同。这是因为我们在打印 IRModule 时使用的是标准格式,而 TVMScript 支持语法糖简化输入。

例如,我们可以将多个操作合并为一行写成:

lv0 = R.matmul(data, R.permute_dims(w0)) + b0

但规范化后的表达式要求一个绑定中只能包含一个操作,因此打印输出是以下形式:

lv: R.Tensor((784, 128), dtype="float32") = R.permute_dims(w0, axes=None)
lv1: R.Tensor((n, 128), dtype="float32") = R.matmul(data, lv, out_dtype="void")
lv0: R.Tensor((n, 128), dtype="float32") = R.add(lv1, b0)

使用 NNModule API 构建 Relax 程序

除了 TVMScript,我们还提供了类似 PyTorch 的 API,用于定义神经网络模型。这个接口更直观,也更容易使用。

在本节中,我们将展示如何使用 Relax 的 NNModule API 定义相同的 MLP 模型。

from tvm.relax.frontend import nn


class NNModule(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(784, 128)
        self.relu1 = nn.ReLU()
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = self.fc1(x)
        x = self.relu1(x)
        x = self.fc2(x)
        return x

在定义完 NNModule 后,我们可以通过 export_tvm 将其导出为 TVM 的 IRModule。

mod, params = NNModule().export_tvm({"forward": {"x": nn.spec.Tensor(("n", 784), "float32")}})
mod.show()

输出:

# from tvm.script import ir as I
# from tvm.script import tir as T
# from tvm.script import relax as R

@I.ir_module
class Module:
    @R.function
    def forward(x: R.Tensor(("n", 784), dtype="float32"), fc1_weight: R.Tensor((128, 784), dtype="float32"), fc1_bias: R.Tensor((128,), dtype="float32"), fc2_weight: R.Tensor((10, 128), dtype="float32"), fc2_bias: R.Tensor((10,), dtype="float32")) -> R.Tensor(("n", 10), dtype="float32"):
        n = T.int64()
        R.func_attr({"num_input": 1})
        with R.dataflow():
            permute_dims: R.Tensor((784, 128), dtype="float32") = R.permute_dims(fc1_weight, axes=None)
            matmul: R.Tensor((n, 128), dtype="float32") = R.matmul(x, permute_dims, out_dtype="void")
            add: R.Tensor((n, 128), dtype="float32") = R.add(matmul, fc1_bias)
            relu: R.Tensor((n, 128), dtype="float32") = R.nn.relu(add)
            permute_dims1: R.Tensor((128, 10), dtype="float32") = R.permute_dims(fc2_weight, axes=None)
            matmul1: R.Tensor((n, 10), dtype="float32") = R.matmul(relu, permute_dims1, out_dtype="void")
            add1: R.Tensor((n, 10), dtype="float32") = R.add(matmul1, fc2_bias)
            gv: R.Tensor((n, 10), dtype="float32") = add1
            R.output(gv)
        return gv

我们还可以在 NNModule 中插入自定义的函数调用,例如张量表达式(Tensor Expression,简称 TE)、TensorIR 函数,或其他 TVM 的打包函数(Packed Functions)。

@T.prim_func
def tir_linear(x: T.handle, w: T.handle, b: T.handle, z: T.handle):
    M, N, K = T.int64(), T.int64(), T.int64()
    X = T.match_buffer(x, (M, K), "float32")
    W = T.match_buffer(w, (N, K), "float32")
    B = T.match_buffer(b, (N,), "float32")
    Z = T.match_buffer(z, (M, N), "float32")
    for i, j, k in T.grid(M, N, K):
        with T.block("linear"):
            vi, vj, vk = T.axis.remap("SSR", [i, j, k])
            with T.init():
                Z[vi, vj] = 0
            Z[vi, vj] = Z[vi, vj] + X[vi, vk] * W[vj, vk]
    for i, j in T.grid(M, N):
        with T.block("add"):
            vi, vj = T.axis.remap("SS", [i, j])
            Z[vi, vj] = Z[vi, vj] + B[vj]


class NNModuleWithTIR(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(784, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        n = x.shape[0]
        # We can call external functions using nn.extern
        x = nn.extern(
            "env.linear",
            [x, self.fc1.weight, self.fc1.bias],
            out=nn.Tensor.placeholder((n, 128), "float32"),
        )
        # We can also call TensorIR via Tensor Expression API in TOPI
        x = nn.tensor_expr_op(topi.nn.relu, "relu", [x])
        # We can also call other TVM packed functions
        x = nn.tensor_ir_op(
            tir_linear,
            "tir_linear",
            [x, self.fc2.weight, self.fc2.bias],
            out=nn.Tensor.placeholder((n, 10), "float32"),
        )
        return x


mod, params = NNModuleWithTIR().export_tvm(
    {"forward": {"x": nn.spec.Tensor(("n", 784), "float32")}}
)
mod.show()

输出:

# from tvm.script import ir as I
# from tvm.script import tir as T
# from tvm.script import relax as R

@I.ir_module
class Module:
    @T.prim_func(private=True)
    def relu(var_env_linear: T.handle, var_compute: T.handle):
        T.func_attr({"tir.noalias": True})
        n = T.int64()
        env_linear = T.match_buffer(var_env_linear, (n, T.int64(128)))
        compute = T.match_buffer(var_compute, (n, T.int64(128)))
        # with T.block("root"):
        for i0, i1 in T.grid(n, T.int64(128)):
            with T.block("compute"):
                v_i0, v_i1 = T.axis.remap("SS", [i0, i1])
                T.reads(env_linear[v_i0, v_i1])
                T.writes(compute[v_i0, v_i1])
                compute[v_i0, v_i1] = T.max(env_linear[v_i0, v_i1], T.float32(0.0))

    @T.prim_func
    def tir_linear(x: T.handle, w: T.handle, b: T.handle, z: T.handle):
        M, K = T.int64(), T.int64()
        X = T.match_buffer(x, (M, K))
        N = T.int64()
        W = T.match_buffer(w, (N, K))
        B = T.match_buffer(b, (N,))
        Z = T.match_buffer(z, (M, N))
        # with T.block("root"):
        for i, j, k in T.grid(M, N, K):
            with T.block("linear"):
                vi, vj, vk = T.axis.remap("SSR", [i, j, k])
                T.reads(X[vi, vk], W[vj, vk])
                T.writes(Z[vi, vj])
                with T.init():
                    Z[vi, vj] = T.float32(0.0)
                Z[vi, vj] = Z[vi, vj] + X[vi, vk] * W[vj, vk]
        for i, j in T.grid(M, N):
            with T.block("add"):
                vi, vj = T.axis.remap("SS", [i, j])
                T.reads(Z[vi, vj], B[vj])
                T.writes(Z[vi, vj])
                Z[vi, vj] = Z[vi, vj] + B[vj]

    @R.function
    def forward(x: R.Tensor(("n", 784), dtype="float32"), fc1_weight: R.Tensor((128, 784), dtype="float32"), fc1_bias: R.Tensor((128,), dtype="float32"), fc2_weight: R.Tensor((10, 128), dtype="float32"), fc2_bias: R.Tensor((10,), dtype="float32")) -> R.Tensor(("n", 10), dtype="float32"):
        n = T.int64()
        R.func_attr({"num_input": 1})
        cls = Module
        with R.dataflow():
            env_linear = R.call_dps_packed("env.linear", (x, fc1_weight, fc1_bias), out_sinfo=R.Tensor((n, 128), dtype="float32"))
            lv = R.call_tir(cls.relu, (env_linear,), out_sinfo=R.Tensor((n, 128), dtype="float32"))
            lv1 = R.call_tir(cls.tir_linear, (lv, fc2_weight, fc2_bias), out_sinfo=R.Tensor((n, 10), dtype="float32"))
            gv: R.Tensor((n, 10), dtype="float32") = lv1
            R.output(gv)
        return gv

使用 Block Builder API 创建 Relax 程序

除了上述 API,我们还提供了 Block Builder API 来创建 Relax 程序。它是一种 IR 构建 API,属于更底层的接口,广泛应用于 TVM 的内部逻辑中,例如编写自定义的 Pass。

bb = relax.BlockBuilder()
n = T.int64()
x = relax.Var("x", R.Tensor((n, 784), "float32"))
fc1_weight = relax.Var("fc1_weight", R.Tensor((128, 784), "float32"))
fc1_bias = relax.Var("fc1_bias", R.Tensor((128,), "float32"))
fc2_weight = relax.Var("fc2_weight", R.Tensor((10, 128), "float32"))
fc2_bias = relax.Var("fc2_bias", R.Tensor((10,), "float32"))
with bb.function("forward", [x, fc1_weight, fc1_bias, fc2_weight, fc2_bias]):
    with bb.dataflow():
        lv0 = bb.emit(relax.op.matmul(x, relax.op.permute_dims(fc1_weight)) + fc1_bias)
        lv1 = bb.emit(relax.op.nn.relu(lv0))
        gv = bb.emit(relax.op.matmul(lv1, relax.op.permute_dims(fc2_weight)) + fc2_bias)
        bb.emit_output(gv)
    bb.emit_func_output(gv)

mod = bb.get()
mod.show()

输出:

# from tvm.script import ir as I
# from tvm.script import tir as T
# from tvm.script import relax as R

@I.ir_module
class Module:
    @R.function
    def forward(x: R.Tensor(("v", 784), dtype="float32"), fc1_weight: R.Tensor((128, 784), dtype="float32"), fc1_bias: R.Tensor((128,), dtype="float32"), fc2_weight: R.Tensor((10, 128), dtype="float32"), fc2_bias: R.Tensor((10,), dtype="float32")) -> R.Tensor(("v", 10), dtype="float32"):
        v = T.int64()
        with R.dataflow():
            lv: R.Tensor((784, 128), dtype="float32") = R.permute_dims(fc1_weight, axes=None)
            lv1: R.Tensor((v, 128), dtype="float32") = R.matmul(x, lv, out_dtype="void")
            lv2: R.Tensor((v, 128), dtype="float32") = R.add(lv1, fc1_bias)
            lv3: R.Tensor((v, 128), dtype="float32") = R.nn.relu(lv2)
            lv4: R.Tensor((128, 10), dtype="float32") = R.permute_dims(fc2_weight, axes=None)
            lv5: R.Tensor((v, 10), dtype="float32") = R.matmul(lv3, lv4, out_dtype="void")
            lv6: R.Tensor((v, 10), dtype="float32") = R.add(lv5, fc2_bias)
            gv: R.Tensor((v, 10), dtype="float32") = lv6
            R.output(gv)
        return lv6

Block Builder API 同样支持构建跨层级的 IRModule,既可以包含 Relax 函数、TensorIR 函数,也可以包含其他 TVM 的打包函数。

bb = relax.BlockBuilder()
with bb.function("forward", [x, fc1_weight, fc1_bias, fc2_weight, fc2_bias]):
    with bb.dataflow():
        lv0 = bb.emit(
            relax.call_dps_packed(
                "env.linear",
                [x, fc1_weight, fc1_bias],
                out_sinfo=relax.TensorStructInfo((n, 128), "float32"),
            )
        )
        lv1 = bb.emit_te(topi.nn.relu, lv0)
        tir_gv = bb.add_func(tir_linear, "tir_linear")
        gv = bb.emit(
            relax.call_tir(
                tir_gv,
                [lv1, fc2_weight, fc2_bias],
                out_sinfo=relax.TensorStructInfo((n, 10), "float32"),
            )
        )
        bb.emit_output(gv)
    bb.emit_func_output(gv)
mod = bb.get()
mod.show()

输出:

# from tvm.script import ir as I
# from tvm.script import tir as T
# from tvm.script import relax as R

@I.ir_module
class Module:
    @T.prim_func(private=True)
    def relu(var_lv: T.handle, var_compute: T.handle):
        T.func_attr({"tir.noalias": True})
        v = T.int64()
        lv = T.match_buffer(var_lv, (v, T.int64(128)))
        compute = T.match_buffer(var_compute, (v, T.int64(128)))
        # with T.block("root"):
        for i0, i1 in T.grid(v, T.int64(128)):
            with T.block("compute"):
                v_i0, v_i1 = T.axis.remap("SS", [i0, i1])
                T.reads(lv[v_i0, v_i1])
                T.writes(compute[v_i0, v_i1])
                compute[v_i0, v_i1] = T.max(lv[v_i0, v_i1], T.float32(0.0))

    @T.prim_func
    def tir_linear(x: T.handle, w: T.handle, b: T.handle, z: T.handle):
        M, K = T.int64(), T.int64()
        X = T.match_buffer(x, (M, K))
        N = T.int64()
        W = T.match_buffer(w, (N, K))
        B = T.match_buffer(b, (N,))
        Z = T.match_buffer(z, (M, N))
        # with T.block("root"):
        for i, j, k in T.grid(M, N, K):
            with T.block("linear"):
                vi, vj, vk = T.axis.remap("SSR", [i, j, k])
                T.reads(X[vi, vk], W[vj, vk])
                T.writes(Z[vi, vj])
                with T.init():
                    Z[vi, vj] = T.float32(0.0)
                Z[vi, vj] = Z[vi, vj] + X[vi, vk] * W[vj, vk]
        for i, j in T.grid(M, N):
            with T.block("add"):
                vi, vj = T.axis.remap("SS", [i, j])
                T.reads(Z[vi, vj], B[vj])
                T.writes(Z[vi, vj])
                Z[vi, vj] = Z[vi, vj] + B[vj]

    @R.function
    def forward(x: R.Tensor(("v", 784), dtype="float32"), fc1_weight: R.Tensor((128, 784), dtype="float32"), fc1_bias: R.Tensor((128,), dtype="float32"), fc2_weight: R.Tensor((10, 128), dtype="float32"), fc2_bias: R.Tensor((10,), dtype="float32")) -> R.Tensor(("v", 10), dtype="float32"):
        v = T.int64()
        cls = Module
        with R.dataflow():
            lv = R.call_dps_packed("env.linear", (x, fc1_weight, fc1_bias), out_sinfo=R.Tensor((v, 128), dtype="float32"))
            lv1 = R.call_tir(cls.relu, (lv,), out_sinfo=R.Tensor((v, 128), dtype="float32"))
            lv2 = R.call_tir(cls.tir_linear, (lv1, fc2_weight, fc2_bias), out_sinfo=R.Tensor((v, 10), dtype="float32"))
            gv: R.Tensor((v, 10), dtype="float32") = lv2
            R.output(gv)
        return lv2

需要注意的是,Block Builder API 的使用体验不如前述 API 那么友好,但它是最低层的 API,并且与 IR 定义紧密耦合。我们推荐普通用户在仅需定义和转换机器学习模型的场景中使用前面提到的 API;而对于需要进行更复杂转换的用户,Block Builder API 提供了更高的灵活性。

总结

本教程演示了如何使用 TVMScript、NNModule API、Block Builder API 以及 PackedFunc API,根据不同的应用场景来创建 Relax 程序。

TVM Relax抽象层:动态深度学习模型编译的新范式 深度学习编译器是连接神经网络模型与多样化硬件后端的关键技术,其核心在于通过中间表示(IR)实现计算图的高效优化与代码生成。传统基于静态计算图的IR(如TVM Relay)在处理动态形状、复杂控制流等场景时面临挑战。TVM Relax作为新一代IR抽象层,通过引入“符号形状”和程序式语义,将计算范式从“计算图”扩展到“计算程序”,支持显式的If-Then-Else条件分支和While循环结构。这一设计使编译器能够更自然地表达运行时数据依赖关系,为动态模型(如变长序列处理、条件计算图)提供原生支持,同时保持与底 阅读详情

相关推荐

TVM Relax抽象层深度解析:从动态形状到控制流的IR设计

编译器中间表示(IR)是机器学习编译优化的核心枢纽。传统静态图IR在处理动态形状、复杂控制流时往往捉襟见肘,难以兼顾表达灵活性与分析透明度。TVM团队为此设计了Relax,一个更贴近高层框架、支持符号形状与显式控制流的可解析IR。它通过函数式、数据流、张量三层抽象,将纯计算与控制流清晰分离,既保留了数据流块内的高效优化潜力,又允许运行时基于实际形状动态调度分支,从而显著简化了变长序列、多模态模型等场景的编译流程。本文从工程实践视角出发,解析Relax的设计动机与三级抽象机制,通过TVMScript示例展示如

weixin_33937778的博客 360

【TVM教程】创建 Relax

本教程演示了如何使用 TVMScript、NNModule API、Block Builder API 以及 PackedFunc API,根据不同的应用场景来创建 Relax 程序(可右键另存为下载)。

HyperAI超神经 297

allegro 约束管理Constraint Manager(一)

介绍Cadence allegro 约束管理器CM的使用方法。

weixin_38975819的博客 8716

TVM Relax 算子库完全指南:tvm.relax.op 命名空间全景解析

`tvm.relax.op` 是 Apache TVM 中 Relax 前端(可微分、可函数式的 IR 层)的**标准算子库**,它把神经网络的卷积、注意力、归一化、池化,以及张量代数、集合通信、内存管理、虚拟机指令等数百个算子统一组织在 `tvm.relax.op` 及其子命名空间中。本文以仓库中的 API 参考文档 [docs/reference/api/python/relax/op.rst

gitblog_01138的博客 639

避坑指南:Qwen2.5-VL图片预处理中常见的5个尺寸错误

本文深入解析了Qwen2.5-VL模型在图片预处理环节中开发者最常遇到的五个尺寸错误,包括动态分辨率对齐、宽高比超标、像素数限制等问题。文章结合源码解读,详细剖析了`process_vision_info`函数和`resize`逻辑,并提供了具体的排查流程图与参数设置建议,旨在帮助开发者构建健壮的预处理流水线,有效规避显存溢出与推理失败的风险。

weixin_29290379的博客 176

国产信创服务器软硬件兼容情况1 --- ARM架构

信创,即信息技术应用创新产业,它是数据安全、网络安全的基础,也是新基建的重要组成部分...

一只猿的自我修养 4741

【TVM教程】理解 Relax 抽象层

TVM 现已更新到 0.21.0 版本,TVM 中文文档已经和新版本对齐。 Apache TVM 是一个深度的深度学习编译框架,适用于 CPU、GPU 和各种机器学习加速芯片。

HyperAI超神经 425

NVMe-MI --- Message Servicing Model(消息服务模型)

本文主要介绍NVMe-MI消息服务模型,两个主要类别是请求消息和响应消息。并介绍带外机制消息服务状态机。

智小星的博客 2014

「TVM教程」理解 Relax 抽象层

TVM 现已更新到 0.21.0 版本,TVM 中文文档已经和新版本对齐。Apache TVM 是一个深度的深度学习编译框架,适用于 CPU、GPU 和各种机器学习加速芯片。在线运行 TVM 学习教程→Relax 是 Apache TVM Unity 策略中使用的一种图抽象方式,用于对机器学习模型进行端到端的优化。Relax 的主要目标是描述机器学习模型的结构与数据流,包括模型不同部分之间的依赖关系与连接方式,以及如何在硬件上执行该模型。wp:heading。

HyperAI超神经 215

从零开始:手把手教你规划与部署华为FusionCompute虚拟化平台(含网络规划避坑指南)

本文详细介绍了华为FusionCompute虚拟化平台的规划与部署流程,特别针对网络规划中的常见问题提供了避坑指南。从硬件软件清单检查、网络平面配置到VRM部署方案选择,帮助用户高效完成部署并优化性能,适用于云计算环境中的虚拟化平台搭建。

weixin_28693447的博客 243

Python实战:用jieba和WordCloud打造电商评论情感分析工具(附完整代码)

本文详细介绍了如何使用Python的jieba分词和WordCloud库构建电商评论情感分析工具,涵盖数据预处理、情感分析、可视化展示等关键步骤,并提供完整代码实现。通过该工具,开发者可以高效分析电商评论数据,挖掘消费者情感倾向,为产品改进和决策提供数据支持。

weixin_30316097的博客 415

TVM Relax 分布式推理基础设施:tvm.relax.distributed 模块全面解析

`tvm.relax.distributed` 是 Apache TVM Relax 前端中专用于**分布式推理(distributed inference)**的 Python 模块,它通过设备网格(DeviceMesh)、数据分布描述(Placement)与分布式张量类型(DTensorType)三件套,把"张量如何切分、复制到多设备"这一意图显式地编码进 IR,再配合一组分布式专用 Pass

gitblog_01151的博客 253

sysrepo 开发者指南(一个基于libyang与支持rpc的数据库)

sysrepo 开发者指南(一个基于libyang与支持rpc的数据库) 日志记录 默认情况下,所有 Sysrepo 日志记录都处于关闭状态。如果启用,日志消息有 3 种输出。它们可以写入stderr、由 处理syslog或简单地传递给回调。 请务必注意,启用 Sysrepo 日志记录也会修改libyang日志记录设置。错误消息被视为标准 Sysrepo 错误,其他严重性较低的消息完全隐藏。要更改此行为,只需在启用 Sysrepo 日志记录后调整libyang日志记录设置。 此外,几乎每个 Sysrepo

weixin_43489394的博客 9228

tvm relax教程(四) ------Relax 程序创建

需要注意:Block Builder API 不如上述 API 友好,但它是最底层的 API,与 IR 定义结合最紧密。它是更底层的 IR builder API,在 TVM 内部逻辑中广泛使用,例如编写自定义 Pass。本教程演示了如何针对不同场景,使用 TVMScript、NNModule API、Block Builder API 以及 PackedFunc API 创建 Relax 程序。本节展示如何仅用高层 Relax 算子,通过 TVMScript 定义一个简单的 MLP 模型。

happyAnger6的专栏 208

OpenCloudOS9操作系统搭建Confluence8.2.1+Jira企业级WIKI

Atlassian Confluence是一个专业的企业知识管理与协同软件,可用于构建企业wiki

背锅神童的博客 1022

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

TVM Relax 变换 Pass 体系全解析:tvm.relax.transform 模块指南

`tvm.relax.transform` 是 Apache TVM Relax 前端(面向大模型、可微分 IR 的下一代 IR)的核心变换模块,负责将高层级 Relax 程序逐级下探到可执行的 TIR PrimFunc,并承担算子融合、自动微分、布局转换、混合精度、内存规划、外部代码生成(BYOC)等关键优化。本文以仓库中 [docs/reference/api/python/relax/tra

gitblog_00375的博客 248

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

TVM Relax Virtual Machine 架构深度解析:从 Relax IR 到字节码解释执行的完整链路

Relax VM(Relax Virtual Machine)是 Apache TVM 中面向新一代高级 IR(Relax IR)的运行时虚拟机,承担着把高层计算图(`relax.Function`)编译为字节码并在运行时解释执行的任务。本文以仓库中的架构文档 [docs/arch/relax_vm.rst](https://link.gitcode.com/i/7bbac4e7d6cb516b4

gitblog_00857的博客 678

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

TVM Relax 测试工具包实战指南:tvm.relax.testing 模块全解析

`tvm.relax.testing` 是 Apache TVM 的 Relax 高层 IR(可微分编程语言)为开发者准备的一站式测试与工作负载构造工具箱。它既提供了 PyTorch 风格的 `nn.Module` 式建模 API,让你能像写深度学习框架代码一样快速拼装神经网络;也提供了 matmul / attention 等算子的标准测试模块生成器、AST 打印器、跨后端数值比对 instru

gitblog_01085的博客 148

TVM教程-----Export and Load Relax Executables

本教程演示如何将编译好的 Relax module export 为共享对象(shared object),再加载回 TVM runtime,并在交互环境或独立脚本中运行结果。本教程展示如何使用tvm.relaxAPI,将 Relax(或导入的 PyTorch / ONNX)程序变成可部署产物。本教程以 PyTorch 作为源格式,但对 ONNX 模型而言,export/load 工作流相同。对于 ONNX,请使用替代,随后按相同步骤进行 build、export 与 load。

happyAnger6的专栏 227

TVM Relax:重塑深度学习编译器的抽象层设计

深度学习编译器的发展,始终绕不开中间表示(IR)的设计——它决定了优化能走多远,表达能力能有多强。传统图IR擅长表达静态数据流,但在动态形状、复杂控制流和训练场景面前常显乏力。为此,TVM社区推出了Relax,一个重新审视机器学习编译抽象层次的新方案。Relax通过StructInfo统一类型、形状与存储信息,以dataflow块隔离纯计算与副作用,借助符号形状和运行时绑定机制应对动态形状难题。它将结构、算子和执行分层管理,既能描述计算图,也能表达闭包回调等高阶结构,配合Relax VM实现灵活高效的执行。

weixin_33957648的博客 470

TVM Relax BlockBuilder 完全指南:用 Python 构建 Relax IR 的开发者 API

本指南基于 Apache TVM 开源仓库中的 [docs/reference/api/python/relax/block_builder.rst](https://link.gitcode.com/i/744b70f62959583a2a594a3c8f25c74a) 文档,深入讲解 Relax 框架的核心开发者 API——`tvm.relax.block_builder`。它适合想要绕过 T

gitblog_00058的博客 363

TVM Relax抽象层深度解析:从Relay到下一代编译IR

中间表示(IR)是深度学习编译器的核心抽象层,它决定了图优化与代码生成的边界。传统静态图IR受限于变量不可变和粗粒度算子,难以高效表达复杂控制流与精细优化。TVM推出的Relax应运而生,通过引入可变变量、DataflowBlock与BindingBlock分层、纯度标注等机制,重新定义了计算意图与实现细节的边界。这种抽象不仅让图优化pass获得更安全的改写能力,还为算子融合、内存复用等场景提供了更大自由度。在实际部署中,Relax能够灵活处理动态shape、自定义融合策略以及与TensorIR的衔接(如c

weixin_33875839的博客 375

深度学习编译器Relax入门:从TVM到动态图编译实战

深度学习编译器是连接深度学习框架与硬件后端的关键技术,通过中间表示(IR)实现模型优化与跨平台部署。其核心原理是将高级计算图转换为底层硬件指令,从而提升推理性能并降低部署成本。在工程实践中,TVM作为主流编译器栈,通过统一的IR支持多种硬件后端。然而,随着模型动态性需求增长,传统静态图IR面临挑战。Relax作为TVM生态的新一代前端IR,原生支持动态形状与渐进式Lowering,显著提升了编译过程的可控性。本文以TVMScript和动态图编译为例,深入解析Relax在支持Python生态、处理动态计算图方

weixin_34357436的博客 479

Apache TVM Relax 图抽象完全指南:从端到端模型执行到 dataflow 块

Relax 是 Apache TVM 中用于端到端优化机器学习模型的图级抽象(graph abstraction),它以计算图的方式刻画模型的结构、数据流以及各部分之间的依赖关系,从而让编译器能够在"高层神经网络层"与"低层张量算子"之间自由跨越。本文以官方文档 [learning.rst](https://link.gitcode.com/i/c9b1566a21dce95d16745e4772

gitblog_00926的博客 379

TVM Relax深度解析:从程序抽象到动态形状与多后端混编

在深度学习编译器领域,计算图的中间表示(IR)决定了优化能力的上限。传统图IR如Relay擅长表达静态的算子依赖关系,但在内存分配、控制流和动态形状等“执行语义”层面存在明显短板。TVM Relax的提出,正是将抽象层级从“数据流图”升级为带执行语义的“程序表示”,让编译器能显式处理内存生命周期、设备切换和运行时函数调用。它通过DataflowBlock保证无副作用优化,结合ShapeExpr实现动态维度推理,并借助call_packed实现多后端无缝混编。这项技术不仅适用于静态网络部署,更支撑起动态bat

weixin_34199405的博客 405

Apache TVM Relax 深度解析:图抽象、跨层优化与 Dataflow Pattern Language 实战

Relax 是 Apache TVM 技术栈中面向**图优化与图变换**的高层抽象,它与底层张量计算抽象 TensorIR 协同工作,共同完成对整个 `IRModule` 的跨层表示与优化。本文以 [docs/deep_dive/relax/index.rst](https://link.gitcode.com/i/fb302973d404d626231bec6d4457757f) 所组织的 De

gitblog_00626的博客 365
上一篇: 为超1亿种小分子生成8亿张预测质谱,康奈尔大学提出AIMe,融合化学规则/碎裂路径推理/神经网络学习
下一篇: 从膜分割到颗粒定位,深度学习框架MemBrain v2打通冷冻电镜分析全流程,显著提升分析速度和处理通量
HyperAI超神经
博客等级 码龄7年 8872粉丝 1753原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值