【TVM 教程】规约(reduce)

TVM Reduction降低算力 TVM Reduction降低算力 这是有关如何降低算力TVM的介绍材料。像sum / max / min这样的关联约简运算符是线性代数运算的典型构造块。 本文将演示如何降低TVM算力。 from future import absolute_import, print_function import tvm import tvm.testing from tvm import te import numpy as np 描述行数 假设要计算行总数作为示例。用numpy语义可以写成B = numpy.sum 阅读详情

Apache TVM 是一个端到端的深度学习编译框架,适用于 CPU、GPU 和各种机器学习加速芯片。更多 TVM 中文文档可访问 →https://tvm.hyper.ai/
作者:Tianqi Chen
本文介绍如何在 TVM 中规约(reduce)。关联规约算子(如 sum/max/min)是线性代数运算的典型构造块。

from __future__ import absolute_import, print_function

import tvm
import tvm.testing
from tvm import te
import numpy as np

描述行的总和​

在 NumPy 语法中,计算行的总和可以写成 B = numpy.sum(A, axis=1)
下面几行描述了行求和操作。为创建一个规约公式,用 te.reduce_axis 声明了一个 reduction 轴,它接收规约的范围。 te.sum 接收要规约的表达式以及 reduction 轴,并计算声明范围内所有 k 值的总和。
等效的 C 代码如下:

for (int i = 0; i < n; ++i) {
  B[i] = 0;
  for (int k = 0; k < m; ++k) {
    B[i] = B[i] + A[i][k];
  }
}
n = te.var("n")
m = te.var("m")
A = te.placeholder((n, m), name="A")
k = te.reduce_axis((0, m), "k")
B = te.compute((n,), lambda i: te.sum(A[i, k], axis=k), name="B")

Schedule 规约​

有几种方法可以 Schedule Reduce,先打印出默认 Schedule 的 IR 代码

s = te.create_schedule(B.op)
print(tvm.lower(s, [A, B], simple_mode=True))

输出结果:

@main = primfn(A_1: handle, B_1: handle) -> ()
  attr = {"from_legacy_te_schedule": True, "global_symbol": "main", "tir.noalias": True}
  buffers = {A: Buffer(A_2: Pointer(float32), float32, [(stride: int32*n: int32)], [], type="auto"),
             B: Buffer(B_2: Pointer(float32), float32, [(stride_1: int32*n)], [], type="auto")}
  buffer_map = {A_1: A, B_1: B}
  preflattened_buffer_map = {A_1: A_3: Buffer(A_2, float32, [n, m: int32], [stride, stride_2: int32], type="auto"), B_1: B_3: Buffer(B_2, float32, [n], [stride_1], type="auto")} {
  for (i: int32, 0, n) {
    B[(i*stride_1)] = 0f32
    for (k: int32, 0, m) {
      B[(i*stride_1)] = (B[(i*stride_1)] + A[((i*stride) + (k*stride_2))])
    }
  }
}

IR 代码与 C 代码非常相似,reduction 轴类似于普通轴,可以拆分。
以下代码按不同的因子将 B 的行轴和轴进行拆分,得到一个嵌套 reduction。

ko, ki = s[B].split(B.op.reduce_axis[0], factor=16)
xo, xi = s[B].split(B.op.axis[0], factor=32)
print(tvm.lower(s, [A, B], simple_mode=True))

输出结果:

@main = primfn(A_1: handle, B_1: handle) -> ()
  attr = {"from_legacy_te_schedule": True, "global_symbol": "main", "tir.noalias": True}
  buffers = {A: Buffer(A_2: Pointer(float32), float32, [(stride: int32*n: int32)], [], type="auto"),
             B: Buffer(B_2: Pointer(float32), float32, [(stride_1: int32*n)], [], type="auto")}
  buffer_map = {A_1: A, B_1: B}
  preflattened_buffer_map = {A_1: A_3: Buffer(A_2, float32, [n, m: int32], [stride, stride_2: int32], type="auto"), B_1: B_3: Buffer(B_2, float32, [n], [stride_1], type="auto")} {
  for (i.outer: int32, 0, floordiv((n + 31), 32)) {
    for (i.inner: int32, 0, 32) {
      if @tir.likely((((i.outer*32) + i.inner) < n), dtype=bool) {
        B[(((i.outer*32) + i.inner)*stride_1)] = 0f32
      }
      if @tir.likely((((i.outer*32) + i.inner) < n), dtype=bool) {
        for (k.outer: int32, 0, floordiv((m + 15), 16)) {
          for (k.inner: int32, 0, 16) {
            if @tir.likely((((k.outer*16) + k.inner) < m), dtype=bool) {
              let cse_var_1: int32 = ((i.outer*32) + i.inner)
              B[(cse_var_1*stride_1)] = (B[(cse_var_1*stride_1)] + A[((cse_var_1*stride) + (((k.outer*16) + k.inner)*stride_2))])
            }
          }
        }
      }
    }
  }
}

把 B 的行绑定到 GPU 线程,从而构建一个 GPU 内核。

s[B].bind(xo, te.thread_axis("blockIdx.x"))
s[B].bind(xi, te.thread_axis("threadIdx.x"))
print(tvm.lower(s, [A, B], simple_mode=True))

输出结果:

@main = primfn(A_1: handle, B_1: handle) -> ()
  attr = {"from_legacy_te_schedule": True, "global_symbol": "main", "tir.noalias": True}
  buffers = {A: Buffer(A_2: Pointer(float32), float32, [(stride: int32*n: int32)], [], type="auto"),
             B: Buffer(B_2: Pointer(float32), float32, [(stride_1: int32*n)], [], type="auto")}
  buffer_map = {A_1: A, B_1: B}
  preflattened_buffer_map = {A_1: A_3: Buffer(A_2, float32, [n, m: int32], [stride, stride_2: int32], type="auto"), B_1: B_3: Buffer(B_2, float32, [n], [stride_1], type="auto")} {
  attr [IterVar(blockIdx.x: int32, (nullptr), "ThreadIndex", "blockIdx.x")] "thread_extent" = floordiv((n + 31), 32);
  attr [IterVar(threadIdx.x: int32, (nullptr), "ThreadIndex", "threadIdx.x")] "thread_extent" = 32 {
    if @tir.likely((((blockIdx.x*32) + threadIdx.x) < n), dtype=bool) {
      B[(((blockIdx.x*32) + threadIdx.x)*stride_1)] = 0f32
    }
    for (k.outer: int32, 0, floordiv((m + 15), 16)) {
      for (k.inner: int32, 0, 16) {
        if @tir.likely((((blockIdx.x*32) + threadIdx.x) < n), dtype=bool) {
          if @tir.likely((((k.outer*16) + k.inner) < m), dtype=bool) {
            B[(((blockIdx.x*32) + threadIdx.x)*stride_1)] = (B[(((blockIdx.x*32) + threadIdx.x)*stride_1)] + A[((((blockIdx.x*32) + threadIdx.x)*stride) + (((k.outer*16) + k.inner)*stride_2))])
          }
        }
      }
    }
  }
}

规约因式分解和并行化​

构建规约时不能简单地在 reduction 轴上并行化,需要划分规约,将局部规约结果存储在数组中,然后再对临时数组进行规约。
rfactor 原语对计算进行了上述重写,在下面的调度中,B 的结果被写入一个临时结果 B.rf,分解后的维度成为 B.rf 的第一个维度。

s = te.create_schedule(B.op)
ko, ki = s[B].split(B.op.reduce_axis[0], factor=16)
BF = s.rfactor(B, ki)
print(tvm.lower(s, [A, B], simple_mode=True))

输出结果:

@main = primfn(A_1: handle, B_1: handle) -> ()
  attr = {"from_legacy_te_schedule": True, "global_symbol": "main", "tir.noalias": True}
  buffers = {A: Buffer(A_2: Pointer(float32), float32, [(stride: int32*n: int32)], [], type="auto"),
             B: Buffer(B_2: Pointer(float32), float32, [(stride_1: int32*n)], [], type="auto")}
  buffer_map = {A_1: A, B_1: B}
  preflattened_buffer_map = {A_1: A_3: Buffer(A_2, float32, [n, m: int32], [stride, stride_2: int32], type="auto"), B_1: B_3: Buffer(B_2, float32, [n], [stride_1], type="auto")} {
  allocate(B.rf: Pointer(global float32), float32, [(n*16)]), storage_scope = global {
    for (k.inner: int32, 0, 16) {
      for (i: int32, 0, n) {
        B.rf_1: Buffer(B.rf, float32, [(16*n)], [])[((k.inner*n) + i)] = 0f32
        for (k.outer: int32, 0, floordiv((m + 15), 16)) {
          if @tir.likely((((k.outer*16) + k.inner) < m), dtype=bool) {
            B.rf_1[((k.inner*n) + i)] = (B.rf_1[((k.inner*n) + i)] + A[((i*stride) + (((k.outer*16) + k.inner)*stride_2))])
          }
        }
      }
    }
    for (ax0: int32, 0, n) {
      B[(ax0*stride_1)] = 0f32
      for (k.inner.v: int32, 0, 16) {
        B[(ax0*stride_1)] = (B[(ax0*stride_1)] + B.rf_1[((k.inner.v*n) + ax0)])
      }
    }
  }
}

B 的调度算子被重写为 B.f 的规约结果在第一个轴上的和。

print(s[B].op.body)

输出结果:

[reduce(combiner=comm_reducer(result=[(x + y)], lhs=[x], rhs=[y], identity_element=[0f]), source=[B.rf[k.inner.v, ax0]], init=[], axis=[iter_var(k.inner.v, range(min=0, ext=16))], where=(bool)1, value_index=0)]

跨线程规约​

接下来可以在因子轴上进行并行化,这里 B 的 reduction 轴被标记为线程,如果唯一的 reduction 轴在设备中可以进行跨线程规约,则 TVM 允许将 reduction 轴标记为 thread。
也可以直接在规约轴上计算 BF。最终生成的内核会将行除以 blockIdx.x,将 threadIdx.y 列除以 threadIdx.x,最后对 threadIdx.x 进行跨线程规约。

xo, xi = s[B].split(s[B].op.axis[0], factor=32)
s[B].bind(xo, te.thread_axis("blockIdx.x"))
s[B].bind(xi, te.thread_axis("threadIdx.y"))
tx = te.thread_axis("threadIdx.x")
s[B].bind(s[B].op.reduce_axis[0], tx)
s[BF].compute_at(s[B], s[B].op.reduce_axis[0])
s[B].set_store_predicate(tx.var.equal(0))
fcuda = tvm.build(s, [A, B], "cuda")
print(fcuda.imported_modules[0].get_source())

输出结果:

#if defined(__CUDA_ARCH__) && (__CUDA_ARCH__ < 700)
#define __shfl_sync(mask, var, lane, width) \
        __shfl((var), (lane), (width))

#define __shfl_down_sync(mask, var, offset, width) \
        __shfl_down((var), (offset), (width))

#define __shfl_up_sync(mask, var, offset, width) \
        __shfl_up((var), (offset), (width))
#endif

#ifdef _WIN32
  using uint = unsigned int;
  using uchar = unsigned char;
  using ushort = unsigned short;
  using int64_t = long long;
  using uint64_t = unsigned long long;
#else
  #define uint unsigned int
  #define uchar unsigned char
  #define ushort unsigned short
  #define int64_t long long
  #define uint64_t unsigned long long
#endif
extern "C" __global__ void __launch_bounds__(512) default_function_kernel0(float* __restrict__ A, float* __restrict__ B, int m, int n, int stride, int stride1, int stride2) {
  float B_rf[1];
  float red_buf0[1];
  B_rf[0] = 0.000000e+00f;
  for (int k_outer = 0; k_outer < (m >> 4); ++k_outer) {
    if (((((int)blockIdx.x) * 32) + ((int)threadIdx.y)) < n) {
      B_rf[0] = (B_rf[0] + A[((((((int)blockIdx.x) * 32) + ((int)threadIdx.y)) * stride) + (((k_outer * 16) + ((int)threadIdx.x)) * stride1))]);
    }
  }
  for (int k_outer1 = 0; k_outer1 < (((m & 15) + 15) >> 4); ++k_outer1) {
    if (((((int)blockIdx.x) * 32) + ((int)threadIdx.y)) < n) {
      if (((((m >> 4) * 16) + (k_outer1 * 16)) + ((int)threadIdx.x)) < m) {
        B_rf[0] = (B_rf[0] + A[((((((int)blockIdx.x) * 32) + ((int)threadIdx.y)) * stride) + (((((m >> 4) * 16) + (k_outer1 * 16)) + ((int)threadIdx.x)) * stride1))]);
      }
    }
  }
  uint mask[1];
  float t0[1];
  red_buf0[0] = B_rf[0];
  mask[0] = (__activemask() & ((uint)(65535 << (((int)threadIdx.y) * 16))));
  t0[0] = __shfl_down_sync(mask[0], red_buf0[0], 8, 32);
  red_buf0[0] = (red_buf0[0] + t0[0]);
  t0[0] = __shfl_down_sync(mask[0], red_buf0[0], 4, 32);
  red_buf0[0] = (red_buf0[0] + t0[0]);
  t0[0] = __shfl_down_sync(mask[0], red_buf0[0], 2, 32);
  red_buf0[0] = (red_buf0[0] + t0[0]);
  t0[0] = __shfl_down_sync(mask[0], red_buf0[0], 1, 32);
  red_buf0[0] = (red_buf0[0] + t0[0]);
  red_buf0[0] = __shfl_sync(mask[0], red_buf0[0], (((int)threadIdx.y) * 16), 32);
  if (((int)threadIdx.x) == 0) {
    B[(((((int)blockIdx.x) * 32) + ((int)threadIdx.y)) * stride2)] = red_buf0[0];
  }
}

结果内核与 NumPy 进行比较来验证结果内核的正确性。

nn = 128
dev = tvm.cuda(0)
a = tvm.nd.array(np.random.uniform(size=(nn, nn)).astype(A.dtype), dev)
b = tvm.nd.array(np.zeros(nn, dtype=B.dtype), dev)
fcuda(a, b)
tvm.testing.assert_allclose(b.numpy(), np.sum(a.numpy(), axis=1), rtol=1e-4)

用二维规约描述卷积​

在 TVM 中,用简单的二维规约来描述卷积(过滤器大小 = [3, 3],步长 = [1, 1])。

n = te.var("n")
Input = te.placeholder((n, n), name="Input")
Filter = te.placeholder((3, 3), name="Filter")
di = te.reduce_axis((0, 3), name="di")
dj = te.reduce_axis((0, 3), name="dj")
Output = te.compute(
    (n - 2, n - 2),
    lambda i, j: te.sum(Input[i + di, j + dj] * Filter[di, dj], axis=[di, dj]),
    name="Output",
)
s = te.create_schedule(Output.op)
print(tvm.lower(s, [Input, Filter, Output], simple_mode=True))

输出结果:

@main = primfn(Input_1: handle, Filter_1: handle, Output_1: handle) -> ()
  attr = {"from_legacy_te_schedule": True, "global_symbol": "main", "tir.noalias": True}
  buffers = {Input: Buffer(Input_2: Pointer(float32), float32, [(stride: int32*n: int32)], [], type="auto"),
             Filter: Buffer(Filter_2: Pointer(float32), float32, [9], []),
             Output: Buffer(Output_2: Pointer(float32), float32, [((n - 2)*(n - 2))], [])}
  buffer_map = {Input_1: Input, Filter_1: Filter, Output_1: Output}
  preflattened_buffer_map = {Input_1: Input_3: Buffer(Input_2, float32, [n, n], [stride, stride_1: int32], type="auto"), Filter_1: Filter_3: Buffer(Filter_2, float32, [3, 3], []), Output_1: Output_3: Buffer(Output_2, float32, [(n - 2), (n - 2)], [])} {
  for (i: int32, 0, (n - 2)) {
    for (j: int32, 0, (n - 2)) {
      Output[((i*(n - 2)) + j)] = 0f32
      for (di: int32, 0, 3) {
        for (dj: int32, 0, 3) {
          Output[((i*(n - 2)) + j)] = (Output[((i*(n - 2)) + j)] + (Input[(((i + di)*stride) + ((j + dj)*stride_1))]*Filter[((di*3) + dj)]))
        }
      }
    }
  }
}

定义一般交换规约运算​

除了 te.sum, tvm.te.min 和 tvm.te.max 等内置规约操作外,还可以通过 te.comm_reducer 定义交换规约操作。

n = te.var("n")
m = te.var("m")
product = te.comm_reducer(lambda x, y: x * y, lambda t: tvm.tir.const(1, dtype=t), name="product")
A = te.placeholder((n, m), name="A")
k = te.reduce_axis((0, m), name="k")
B = te.compute((n,), lambda i: product(A[i, k], axis=k), name="B")

总结​

本教程演示了如何规约 schedule。
用 reduce_axis 描述规约。
如需并行性(parallelism),用 rfactor 来分解轴。
通过 te.comm_reducer 定义新的规约操作。

LLM推理JIT Kernel实战:CUDA零成本抽象与运行时特化 JIT Kernel是面向大语言模型(LLM)推理场景的现代GPU算子编译范式,其核心在于将传统AOT(预编译)迁移至运行时按需编译,实现模板特化、硬件感知与维度定制。它依托现代C++的constexpr和template机制,在编译期完成shape约束、内存布局优化与指令选择,从而规避分支预测开销、shared memory bank conflict及PCIe带宽瓶颈。技术价值体现在极致性能(如1M context下Top-K延迟压至15μs)、开发效率跃升(clangd实时索引、编译从28分钟降至4秒 阅读详情

相关推荐

矩阵最小值计算:从基础遍历到并行优化与稀疏矩阵处理

在数据处理与科学计算中,矩阵作为高维信息的核心结构,其基本操作如求最小值是算法设计的基础。该操作的核心原理是通过遍历与比较确定最小元素,时间复杂度为O(m*n)。理解这一原理对于优化计算性能至关重要,尤其是在处理大规模数据时。从技术价值看,高效的矩阵最小值计算能显著提升机器学习、实时传感器数据处理等场景的系统效率。针对海量数据,可通过向量化、缓存友好访问、多线程/多进程并行以及GPU加速等策略进行优化。对于稀疏矩阵,只需遍历非零元素,能将复杂度从O(m*n)降至O(nnz)。本文深入探讨了这些性能优化策略及

weixin_30691871的博客 387

Reduce归约 证明原理

一、归约 Reducing A(已知的) to B(要证明的) 思想: 我们现在遇到了个问题,可以把它转化到一个某个已解决的问题上,而不是一定要直接解决这个问题 概念描述: 设计一个函数f(x),把问题A的输入A_input转换成问题B的一个输入B_input=f(x),这样就能用问题B的解法来求解。(输出真或假) A可以被归约到B。 难点:转换函数f(x)的设计必须要保证问题B的输出结果和相应的问题A上的答案保持一致。 可视化归约 即A<=B ,B比A难,如果B.

软件工程小施同学 的专栏 2136

【信息科学与工程学】【数据中心】 第十九篇 MFU的优化提升方法03

等级模块类型子模块子子模块功能描述MFU影响因子优化优先级L0​算术逻辑单元(ALU)标量ALU整数ALU标量整数运算α_int = 0.1-0.3中浮点ALU标量浮点运算α_fp_scalar = 0.2-0.4中向量处理单元(VPU)SIMD单元128-bit SIMD短向量运算β_SIMD128 = 0.3-0.6高256-bit SIMD中向量运算β_SIMD256 = 0.4-0.7高512-bit SIMD长向量运算β_SIMD512 = 0.5-0.8极高矩阵处理单元(MPU)Tensor C

weixin_49199313的博客 1011

使用TVM优化GEMM

优化时间(s)default2.930760+tile0.261980+vectorize0.16041+parallel0.025833。

weixin_44604698的博客 510

【信息科学与自动化】计算机科学与自动化——第三百零二篇 大语言模型的训练/推理/微调01

PagedAttention将逻辑连续的KV Cache划分为固定大小的物理块(page),通过页表映射,实现零碎片和高效共享(如beam search)。物理块总数由总显存决定。:d: head维度(64~128),N: 序列长度(可达32K),Br​,Bc​: tile大小(通常64~256),d​为缩放因子。若验证通过则接受,否则回退。4. 进行 P 轮循环:在第 r 轮,每个GPU接收来自前驱的K/V块(或使用本地块),计算局部注意力,更新 mi​,li​,Oi​,然后将自己的K/V块发送给后继。

weixin_49199313的博客 156

【信息科学与工程学】【数据科学】数据科学领域 第六篇 算法设计 01

算法设计

weixin_49199313的博客 1501

CUDA学习(一):并行规约Reduce

规约(Reduce)可以认为是对所有数组添加一种规则或者说规范,这是一种非常典型的并行算法,给定N个输入数据,指定符合结合律的二元操作符最终得到规约结果,而这个二元操作符便包括求和,最大最小,点积等。本文主要介绍的是求和的并行规约算法。经过上述的一系列优化方法可以使得并行规约的运行时间得到大幅度的提升,可以看到循环展开的优化效果是非常明显的。作为入门级优化项目,完整的实现上述优化方法还是可以很好的帮助我们入门并行优化。

qq_44161734的博客 3112

【信息科学与工程学】【运营科学】第二篇 C4信息与通信网络运营 (C4) ——数据中心网络运营04

典型值:λ1​∈[−0.02,−0.01], λ2​∈[−0.01,0], η1​,η3​∈[0.1,0.3], η2​,η4​∈[0.05,0.15]参数:δ1​∈[−0.8,−0.3], δ2​∈[−0.5,−0.2], δ3​∈[−0.4,−0.1], δ4​∈[−0.6,−0.2]参数:φ1​∈[0.1,0.3], φ2​∈[−0.2,−0.05], φ3​∈[−0.1,0.1], φ4​∈[−0.3,−0.1]参数:α∈[0.3,0.6], β∈[0.2,0.4], γ∈[0.01,0.03]

weixin_49199313的博客 1209

Stream API ---- 规约Reduce

Stream 规约 规约操作(reduction operation)又被称作折叠操作(fold),是通过某个连接动作将所有元素汇总成一个汇总结果的过程。元素求和、求最大值或最小值、求出元素总个数、将所有元素转换成一个列表或集合,都属于规约操作。Stream类库有两个通用的规约操作reduce()和collect(),也有一些为简化书写而设计的专用规约操作,比如sum()、max()、min()、...

哈 1168

HFSS螺旋线圈的优化设计与高效仿真实践

本文详细介绍了HFSS螺旋线圈的优化设计与高效仿真实践,涵盖核心参数设置、参数化建模、仿真加速技巧及结果分析。通过HFSS软件实现螺旋线圈的高效仿真,特别适用于无线充电和RFID系统设计,提升设计效率与性能验证准确性。

weixin_30235225的博客 445

PCIe链路均衡实战:从Preset调节到系数优化的完整指南(附Synopsy IP案例)

本文深入解析PCIe链路均衡技术,从Preset调节到系数优化的全流程实战指南,特别针对PCIe 3.0/4.0中的Recovery.Equalization状态进行详细说明。通过Synopsy IP案例,展示如何应对高速信号完整性挑战,优化前向反馈均衡(FFE)机制,提升系统性能。

peace的博客 1054

CANN MinDim & MaxDim 算子设计

> 适配硬件:Atlas A2 训练系列产品 / Atlas A3 系列产品 | 开发语言:Ascend C > 内部原生算子:`ArgMinWithValue`(对应 `aclnnMinDim`)、`ArgMaxWithValue`(对应 `aclnnMaxDim`) # 需求背景 ## 需求来源 社区任务 `20260529-6 MinDim&MaxDim`:参考昇腾版本内置 `acln

gitblog_00699的博客 473

STM32H750VBT6在Keil5下载失败?5步搞定Flash Download Failed Cortex-M7错误

本文针对STM32H750VBT6在Keil5中遇到的“Flash Download Failed - Cortex-M7”错误,提供了系统性的五步排查法。从硬件连接到驱动检查,再到核心的Flash算法配置、链接脚本核对,以及芯片保护状态等深度排查,帮助开发者快速定位并解决下载失败问题,尤其适用于处理内部Flash与外部QSPI Flash的混合应用场景。

weixin_29239279的博客 481

CANN atvoss向量模板设计原则深度解析:昇腾Vector Core向量计算模式与高效向量化编程规范——Tile-Layer-Stripe三层调度架构与双缓冲流水线实战完全开发指南

幸运的是,PyPI 上有几个包可以在上节提到的 Python shell 中实现这些功能。遗憾的是,pdb 来源于 bdb,所以第一次使用 pdb 可能会有点难以适应,因为诸如 h、然后介绍了 Python 开发的现代方法,令人吃惊的是,开发这些。pdb 中的调试会话也非常简单,并没有提供类似 tab 补全或代码高亮之类的附加功能。互联网为 Python 开发者提供了丰富的有用资源。Python 提供了许多好用的数据类型,既包括数字类型,也包括集合类型。当然,每种类型的定义会有些许差异,也有一些(可能)

qq_17776737的博客 250

LlamaIndex 入门实战

LlamaIndex是一个“数据框架”,用于帮助构建LLM应用程序。它提供了各种工具,包括数据连接器,用于摄取现有数据源和数据格式(API,PDF,文档,SQL等),以及用于将数据结构化(索引,图形)以便与LLM轻松使用的方式。此外,LlamaIndex还提供了高级的检索/查询接口,可以输入任何LLM输入提示,并返回检索到的上下文和增强知识的输出。它还允许与外部应用程序框架(如LangChain,Flask,Docker,ChatGPT等)轻松集成。

AIGC搞起 1万+

Microsoft AI SDK 与 SAP ABAP:让企业级 AI 能力触手可及的深度整合指南

借助 Microsoft AI SDK,ABAP 开发者无需跳出熟悉的事务码与数据字典,就能把 GPT‑4 的强大语言理解与生成能力深度植入采购、销售、财务等核心业务流程。只要掌握“初始化 SDK → 构造 Prompt → 解析输出”这一范式,未来无论 Azure OpenAI、OpenAI 还是本地化 LLM,都能在同一套代码骨架内快速切换,实现真正的“AI 即服务”。现在,就让我们在下一行 ABAP 里拥抱智能未来。参考链接均于 2025‑07‑22 提取,推荐读者结合实际版本进一步验证。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 432

AI异构计算工程师笔试攻略:CUDA、算子融合与深度学习框架底层

在人工智能基础设施快速演进的今天,深度学习模型的训练与推理早已不再局限于简单的Python调用,而是深度依赖GPU、FPGA等异构计算资源的底层优化能力。理解硬件体系结构、并行编程模型与深度学习框架的实现原理,成为高性能计算领域工程师的核心素养。从CUDA编程中的线程束调度、共享内存与访存合并,到算子融合如何减少全局内存读写、提升计算效率,再到多卡并行训练中的通信与显存管理,这些技术共同构成了现代AI系统的性能基石。无论是面向大型互联网公司的校招笔试,还是日常推理引擎与训练框架的研发实践,掌握这些知识都能帮

weixin_34163553的博客 279

【微服务】Java 对接飞书多维表格使用详解

Java 对接飞书多维表格使用详解

congge_study的博客 1万+

flashinfer attention kernel分析

分析flashinfer代码库中attention算子的实现细节

u010643777的专栏 794

【MTK平台】【wpa_supplicant】关于wpa_supplicant/p2p_supplicant.c文件的介绍

本文主要介绍external/wpa_supplicant_8/wpa_supplicant/p2p_supplicant.c 这个文件这个文件里面有个核心的方法就是。

专业开发者的博客,一个从事Android WiFi和蓝牙的工程师 725

智能化教育改革中的教师角色转变:AI应用架构师如何设计“人机协同”系统?

个性化与规模化的矛盾:如何用AI实现规模化的个性化学习,同时保留教师的“人文温度”?自动化与自主性的矛盾:如何用AI自动化流程(如批改),同时避免教师沦为“AI操作工人”?数据驱动与经验驱动的矛盾:如何平衡AI的“数据决策”与教师的“经验决策”,避免“算法偏见”或“经验固化”?在智能化教育改革中,教师始终是教育的核心——AI系统是“辅助工具”,而非“替代者”。

小白菜的博客 1269

让语音转文字带时间戳:深入whisper-tiny.en的alignment_heads对齐头与时间戳Token机制

whisper-tiny.en 是 OpenAI Whisper 最小英文语音识别模型的 ONNX 版本,专为 Transformers.js 设计,可在浏览器和 Node.js 中跑语音转文字。它的隐藏亮点是:不仅能"听出文字",还自带**时间戳 Token 机制**与 **alignment_heads(对齐头)** 两套方案,帮你生成精确到 0.01 秒的词级时间戳,轻松做出字幕、卡拉OK

gitblog_00767的博客 408

廖雪峰Python教程[完整版]

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

CANN / cann-recipes-infer:NPU DeepSeek-V3.2-Exp TileLang算子开发实践

近年来AI大模型出现爆炸式增长,其对高性能算子的要求也越来越高。但开发高性能的算子并非易事,传统 AI 编程涉及复杂的调度优化(如线程绑定、布局优化、张量化等),需要大量手动编写调度代码,导致开发效率低且难以维护。在这种背景下,专门针对AI领域的DSL应运而生。尽管最近针对AI工作负载的DSL极大的简化了高性能算子内核的创建,即使数据流被明确暴露,但它们仍然将大多数低级优化与算子内核紧密交织在一起

gitblog_00476的博客 899

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

从论文到生产:大模型工程化实现的核心架构与优化策略

在深度学习领域,将前沿的学术论文转化为稳定、高效的生产级模型,是算法落地面临的核心挑战。这背后涉及一系列关键的工程化原理,包括分布式训练、计算图优化、显存管理等核心技术。分布式训练通过并行计算加速模型迭代,其关键在于通信优化与容错设计;计算图优化通过算子融合等技术,减少内核启动开销,提升计算效率;而显存管理则利用梯度检查点、混合精度训练等技术,突破硬件限制以训练更大模型。这些技术的价值在于,它们直接决定了模型训练的成本、效率与稳定性,是算法创新实现商业价值的基础。在实际应用中,无论是大规模语言模型还是多模态

weixin_34184158的博客 400

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

【社区任务】SoftmaxCrossEntropyWithLogits算子设计文档

### 1.1 需求来源 通过社区任务完成 `SoftmaxCrossEntropyWithLogits` 算子 Ascend C 化开发,参考昇腾 CANN 内置 TBE 实现,在昇腾 NPU 上实现功能一致、性能满足验收要求的算子,并按任务书要求提交到昇腾算子开源仓 `ops-nn` 的 `experimental/activation` 目录(`https://gitcode.com/ca

gitblog_01098的博客 435

CUDA生态核心组件解析:cuBLAS、cuDNN、NCCL、Triton与CUTLASS实战指南

在GPU加速计算领域,高性能计算库是释放硬件潜力的关键。其核心原理在于通过高度优化的底层实现,将通用计算任务映射到GPU的并行架构上,从而大幅提升计算吞吐量。从技术价值看,这些库不仅提供了接近硬件极限的性能,更通过标准化的接口降低了开发门槛,使得开发者能够专注于算法本身而非底层硬件细节。在深度学习和大模型训练等应用场景中,矩阵运算、卷积计算和多设备通信是主要的性能瓶颈。针对这些挑战,NVIDIA CUDA生态提供了一系列核心组件:cuBLAS作为基础线性代数库,为矩阵乘法等核心操作提供极致优化;cuDNN则

weixin_30607659的博客 398
上一篇: 入选NeurIPS 24!浙大团队提出全新去噪蛋白质语言模型DePLM,突变效应预测优于SOTA模型
下一篇: AI助力RNA病毒研究历史性突破,中山大学等用深度学习模型,发现超过16万种新病毒
HyperAI超神经
博客等级 码龄7年 8873粉丝 1753原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值