Python API 参考

Python 模块

import lacinfer

本章中的类和函数均由 lacinfer 模块导出。Python API 将底层 C++ 对象封装为 Python 对象,并自动管理相关资源,用户通常不需要手动释放。从 program 获取的 module、从 module 获取的 instruction_ref 等对象引用所属计算图中的内容,不应在所属计算图失效后继续使用。

张量形状(lacinfer.shape)

描述张量的数据类型、维度和内存布局。

构造函数

lacinfer.shape(
    *,
    type="float",
    lens=[1],
    strides=None,
    permutation=None,
    dyn_dims=None,
) -> lacinfer.shape

签名中的 *1表示其后的所有参数均须通过关键字传入。

参数 类型 默认值 说明
type str "float" 元素类型名称
lens list[int] [1] 静态形状的各维长度
strides list[int] 或 None None 显式步长;长度必须与 lens 相同
permutation list[int] 或 None None 维度排列
dyn_dims list[shape.dynamic_dimension] 或 None None 动态形状的各维范围

dyn_dims 存在时使用动态形状构造路径。静态形状中,strides 和 permutation 不应同时提供。

元素类型

type 接受类型枚举名称及实现支持的简写。建议使用下列明确名称:

名称 含义
bool_type 布尔值
half_type IEEE FP16 [实验性]
float_type IEEE FP32
double_type IEEE FP64
uint8_type 无符号 8 位整数
int8_type 有符号 8 位整数
uint16_type 无符号 16 位整数
int16_type 有符号 16 位整数
int32_type 有符号 32 位整数
int64_type 有符号 64 位整数
uint32_type 无符号 32 位整数
uint64_type 无符号 64 位整数
fp8e4m3fnuz_type FP8 E4M3 FNUZ [实验性]
fp8e4m3fn_type FP8 E4M3 FN [实验性]
fp8e5m2_type FP8 E5M2 [实验性]
bf16_type BF16 [实验性]
fp8e5m2fnuz_type FP8 E5M2 FNUZ [实验性]

上述 FP8、FP16 和 BF16 类型在当前版本中属于 [实验性] 类型,其兼容性和行为可能在后续版本中调整。

对应枚举可通过 lacinfer.shape.type_t 访问。

查询方法

shape.type()

shape.type() -> lacinfer.shape.type_t

返回元素类型枚举。

shape.type_string()

shape.type_string() -> str

返回元素类型的字符串名称。

shape.lens()

shape.lens() -> list[int]

返回各维静态长度。

shape.strides()

shape.strides() -> list[int]

返回各维步长,以元素为单位。

shape.ndim()

shape.ndim() -> int

返回维数。

shape.elements()

shape.elements() -> int

返回逻辑元素总数。

shape.bytes()

shape.bytes() -> int

返回形状占用的字节数。

shape.type_size()

shape.type_size() -> int

返回单个元素占用的字节数。

shape.dyn_dims()

shape.dyn_dims() -> list[lacinfer.shape.dynamic_dimension]

返回动态维度描述。

shape.packed()

shape.packed() -> bool

当张量布局紧凑、元素之间没有间隙时返回 True。

shape.transposed()

shape.transposed() -> bool

当步长表示转置布局时返回 True。

shape.broadcasted()

shape.broadcasted() -> bool

当至少一个步长为零并表示广播维度时返回 True。

shape.standard()

shape.standard() -> bool

当形状为标准布局,即紧凑且未转置时返回 True。

shape.scalar()

shape.scalar() -> bool

当所有步长均为零时返回 True。

shape.dynamic()

shape.dynamic() -> bool

当形状包含动态维度时返回 True。

shape 支持使用 == 和 != 比较,并可通过 Python 内置函数 repr(shape) 获取其字符串表示。

动态维度(lacinfer.shape.dynamic_dimension) [实验性]

描述单个动态维度的范围和优选值。

构造函数

lacinfer.shape.dynamic_dimension() -> dynamic_dimension
lacinfer.shape.dynamic_dimension(min: int, max: int) -> dynamic_dimension
lacinfer.shape.dynamic_dimension(
    min: int,
    max: int,
    optimals: set[int],
) -> dynamic_dimension
属性 类型 说明
min int 运行时维度下界
max int 运行时维度上界
optimals set[int] 编译器重点优化的维度取值

dynamic_dimension.is_fixed()

dynamic_dimension.is_fixed() -> bool

当 min == max 时返回 True。

参数(lacinfer.argument)

将形状与数据缓冲区关联,并实现 Python 缓冲区协议。

构造函数

lacinfer.argument(data: Buffer) -> lacinfer.argument

data 必须实现缓冲区协议,例如 NumPy 数组。构造过程从缓冲区的数据类型、形状和步长推导张量形状,并引用其数据;调用方必须保证源缓冲区在使用期间有效。

lacinfer.create_argument()

lacinfer.create_argument(
    s: lacinfer.shape,
    values: list[float],
) -> lacinfer.argument

创建具有指定形状和值的参数。len(values) 必须等于 s.elements(),否则抛出异常。输入值按目标元素类型转换。

lacinfer.generate_argument()

lacinfer.generate_argument(
    s: lacinfer.shape,
    seed: int = 0,
) -> lacinfer.argument

使用指定种子生成测试数据。该函数不用于生成安全随机数。

lacinfer.fill_argument()

lacinfer.fill_argument(
    s: lacinfer.shape,
    value: int | float,
) -> lacinfer.argument

创建指定形状的参数,并用同一个值填充全部元素。

lacinfer.argument_from_pointer()

lacinfer.argument_from_pointer(
    shape: lacinfer.shape,
    address: int,
) -> lacinfer.argument

用现有地址构造零拷贝参数。函数不验证地址的可访问范围,也不取得内存所有权。地址必须指向至少 shape.bytes() 字节的有效内存,并满足目标对内存位置和对齐的要求。

属性获取函数

argument.get_shape()

argument.get_shape() -> lacinfer.shape

返回参数形状。

argument.data_ptr()

argument.data_ptr() -> int

返回底层数据的内存地址。返回值不持有数据缓冲区,也不会延长其生命周期;使用该地址期间,必须保证对应的 argument 及其底层缓冲区仍然有效。

argument.tolist()

argument.tolist() -> list

按逻辑形状把数据复制为 Python 列表。

argument.save()

lacinfer.argument.save(arg: lacinfer.argument, filename: str) -> None

静态方法。把参数的形状和数据编码到文件中。

argument.load()

lacinfer.argument.load(filename: str) -> lacinfer.argument

静态方法。从参数文件恢复对象。

argument 支持 ==、!=、repr() 和缓冲区访问。

编译目标(lacinfer.target)

表示程序编译目标。该类不直接公开构造函数,应使用 get_target() 创建。

lacinfer.get_target()

lacinfer.get_target(name: str) -> lacinfer.target
参数 说明
name="gpu" GPU 目标
name="ref" 参考目标

当前发布版本只提供上述两个目标。其他名称会导致异常。

指令引用(lacinfer.instruction_ref)

表示模块中的一条指令。实例由 module 方法或模块迭代器返回,不能直接构造。

instruction_ref.shape()

instruction_ref.shape() -> lacinfer.shape

返回指令输出形状。

instruction_ref.op()

instruction_ref.op() -> lacinfer.op

返回指令关联的操作。

instruction_ref.inputs()

instruction_ref.inputs() -> list[lacinfer.instruction_ref]

返回输入指令。

instruction_ref.outputs()

instruction_ref.outputs() -> list[lacinfer.instruction_ref]

返回以当前指令为输入的指令。

instruction_ref.name()

instruction_ref.name() -> str

返回指令名称。

instruction_ref.get_literal()

instruction_ref.get_literal() -> lacinfer.argument

返回字面量指令保存的数据。只应对字面量指令调用。

该类型支持哈希、== 和 !=。

计算图模块(lacinfer.module)

表示程序中的一个计算图模块。实例通过 program 的 get_main_module() 或 create_module() 获取,不能直接构造。模块对象的有效期依赖所属程序。

module.print()

module.print() -> None

向标准输出打印模块指令。

module.add_instruction()

module.add_instruction(
    op: lacinfer.op,
    args: list[lacinfer.instruction_ref],
    mod_args: list[lacinfer.module] = [],
) -> lacinfer.instruction_ref

向模块添加操作指令。args 是操作的数据输入,即产生各输入值的指令引用;mod_args 是控制流操作使用的子模块。

module.add_literal()

module.add_literal(
    data: lacinfer.argument | Buffer,
) -> lacinfer.instruction_ref

向模块添加常量。缓冲区数据类型、维度和步长用于确定字面量形状。

module.add_parameter()

module.add_parameter(
    name: str,
    shape: lacinfer.shape,
) -> lacinfer.instruction_ref

添加命名输入参数。模块内参数名必须唯一。

module.add_return()

module.add_return(
    args: list[lacinfer.instruction_ref],
) -> lacinfer.instruction_ref

添加返回指令。

module.replace_return()

module.replace_return(
    args: list[lacinfer.instruction_ref],
) -> lacinfer.instruction_ref

用新的返回值替换模块现有返回指令。

模块支持 repr() 和迭代。迭代元素类型为 instruction_ref;迭代期间不得销毁或修改所属模块。

操作(lacinfer.op)

描述一个操作及其属性。

构造函数

lacinfer.op(name: str, **attributes) -> lacinfer.op

name 必须是当前构建已注册的操作名。attributes 用于设置操作属性;支持的属性名称、类型和取值由 name 指定的操作决定。例如,reshape 操作可通过 dims 指定目标维度。属性不受支持或取值无效时会产生异常。

op.name()

op.name() -> str

返回操作名称。

op.values()

op.values() -> dict[str, object]

返回操作属性。

op.pooling_mode

池化模式枚举:

枚举值 说明
lacinfer.op.pooling_mode.average 平均池化
lacinfer.op.pooling_mode.max 最大池化
lacinfer.op.pooling_mode.lpnorm Lp 范数池化

op.rnn_direction

循环神经网络方向枚举:

枚举值 说明
lacinfer.op.rnn_direction.forward 正向
lacinfer.op.rnn_direction.reverse 反向
lacinfer.op.rnn_direction.bidirectional 双向

程序(lacinfer.program)

表示可构建、编译、执行和序列化的计算程序。

构造函数

lacinfer.program() -> lacinfer.program

创建具有空主模块的程序。

program.get_parameter_names()

program.get_parameter_names() -> list[str]

返回全部输入参数名称。

program.get_parameter_shapes()

program.get_parameter_shapes() -> dict[str, lacinfer.shape]

返回参数名到形状的映射。

program.get_output_shapes()

program.get_output_shapes() -> list[lacinfer.shape]

返回全部程序输出的形状。

program.is_compiled()

program.is_compiled() -> bool

返回程序是否已经编译。

program.compile()

program.compile(
    t: lacinfer.target,
    offload_copy: bool = True,
    fast_math: bool = True,
    exhaustive_tune: bool = False,
) -> None
参数 说明
t 编译目标
offload_copy 为 GPU 等使用独立设备内存的目标,在编译时加入必要的数据复制:将输入从主机内存复制到设备内存,并将结果复制回主机内存
fast_math 启用速度更快的近似数学实现,可能产生轻微精度差异
exhaustive_tune 扩大内核调优搜索,增加首次编译时间

该方法原地修改程序。图修改和量化应在编译前完成。

program.get_main_module()

program.get_main_module() -> lacinfer.module

返回主模块。

program.create_module()

program.create_module(name: str) -> lacinfer.module

创建命名子模块并加入程序。

program.run()

program.run(
    params: dict[str, Buffer],
) -> list[lacinfer.argument]

同步执行已编译程序。

参数 说明
params 参数名到缓冲区对象的映射;argument 也实现缓冲区协议

参数名称、元素类型、维度、布局与内存位置必须符合编译结果。返回值按程序返回指令的顺序排列。

program.run_async()

program.run_async(
    params: dict[str, Buffer],
    stream: int,
    stream_name: str,
) -> list[lacinfer.argument]

在指定原生流上异步提交程序。

参数 说明
params 输入缓冲区映射
stream 原生流指针的地址
stream_name 运行时用于识别流类型的名称

返回时计算可能尚未完成。调用方负责保持输入、输出和流有效,并在访问结果或复用内存前同步。

program.to_py()

program.to_py() -> str

返回以 Python 风格表示程序的文本。

program.sort()

program.sort() -> None

原地按拓扑关系整理模块中的指令。

program.print()

program.print() -> None

向标准输出打印程序。

program 支持 ==、!= 和 repr()。

ONNX 解析

lacinfer.parse_onnx()

lacinfer.parse_onnx(
    filename: str,
    default_dim_value: int = 0,
    default_dyn_dim_value: lacinfer.shape.dynamic_dimension =
        lacinfer.shape.dynamic_dimension(1, 1),
    dim_params: dict[str, lacinfer.shape.dynamic_dimension] = {},
    map_input_dims: dict[str, list[int]] = {},
    map_dyn_input_dims:
        dict[str, list[lacinfer.shape.dynamic_dimension]] = {},
    skip_unknown_operators: bool = False,
    print_program_on_error: bool = False,
    max_loop_iterations: int = 10,
    limit_max_iterations: int = 65535,
) -> lacinfer.program
参数 说明
filename ONNX 模型路径
default_dim_value 未确定维度的固定默认值;当前绑定默认值为 0
default_dyn_dim_value 未确定维度的默认动态范围
dim_params ONNX 符号维度名到动态范围的映射
map_input_dims 指定输入名到静态维度的覆盖映射
map_dyn_input_dims 指定输入名到动态维度列表的覆盖映射
skip_unknown_operators 是否跳过未知操作并继续解析
print_program_on_error 解析失败时是否打印已构建的程序
max_loop_iterations Loop 未提供 trip count 时的默认最大迭代数
limit_max_iterations Loop 允许的迭代数硬上限

返回未编译程序。输入覆盖名称必须与模型输入名精确一致。同一输入不要同时放入静态和动态覆盖映射。

lacinfer.parse_onnx_buffer()

lacinfer.parse_onnx_buffer(
    filename: str,
    default_dim_value: int = 0,
    default_dyn_dim_value: lacinfer.shape.dynamic_dimension =
        lacinfer.shape.dynamic_dimension(1, 1),
    map_input_dims: dict[str, list[int]] = {},
    map_dyn_input_dims:
        dict[str, list[lacinfer.shape.dynamic_dimension]] = {},
    skip_unknown_operators: bool = False,
    print_program_on_error: bool = False,
    external_data_path: str = "",
) -> lacinfer.program

尽管绑定参数名为 filename,该参数实际接收包含完整 ONNX 模型的字节序列。external_data_path 指定外部权重数据所在目录。其余参数与 parse_onnx() 含义相同。

lacinfer.get_onnx_operators()

lacinfer.get_onnx_operators() -> list[str]

返回当前构建支持的 ONNX 操作名称。

量化

量化函数原地修改 program,应在编译前调用。

lacinfer.quantize_int8()

lacinfer.quantize_int8(
    prog: lacinfer.program,
    t: lacinfer.target,
    calibration: list[dict[str, lacinfer.argument]] = [],
    ins_names: set[str] = {
        "dot", "convolution", "convolution_backwards",
        "pooling", "add", "sdpa"
    },
    force_i8_output: bool = False,
    save_quantized_lir_path: str = "",
    per_channel_ops: set[str] = set(),
    asymmetric_activation_ops: set[str] = set(),
    nodes_to_exclude: set[str] = set(),
) -> None
参数 说明
prog 待量化程序
t 执行校准数据的目标
calibration 校准样本列表,每个元素是完整的程序输入映射
ins_names 要量化的 LACInfer 操作名集合
force_i8_output 为可量化的浮点模型输出插入对称 INT8 量化 [实验性]
save_quantized_lir_path 非空时将量化后的程序以 LIR 格式保存到指定路径
per_channel_ops 启用逐通道量化的操作类型集合
asymmetric_activation_ops 对非权重输入启用非对称量化的操作集合;权重仍采用对称量化 [实验性]
nodes_to_exclude 按源模型节点名排除量化,精确匹配;未知名称被忽略 [实验性]

校准数据的参数名、类型和形状必须与程序输入匹配。sdpa 表示标准 ONNX 域的 Attention 路径。pooling 量化为 [实验性] 功能,当前仅支持平均池化(Average Pooling)。

per_channel_ops 当前支持以下节点类型:

节点类型 量化对象 通道轴
convolution 第 2 个输入,即权重 0
convolution_backwards 第 2 个输入,即权重 1

asymmetric_activation_ops 当前只支持 convolution,作用于第 1 个输入,即激活输入。该选项会导致性能下降,当前版本不推荐使用;仅在对 mAP 有极高要求,并经实际模型精度与性能测试确认收益后考虑启用。

nodes_to_exclude 只对具有源模型节点名、且进入 INT8 量化候选的节点生效。名称必须精确匹配;未命名、名称未知或在量化前已被优化掉的节点不会被排除。

lacinfer.quantize_fp16() [实验性]

lacinfer.quantize_fp16(
    prog: lacinfer.program,
    ins_names: list[str] = ["all"],
) -> None

把指定操作转换为 FP16。["all"] 表示使用全部适用操作。

lacinfer.quantize_bf16() [实验性]

lacinfer.quantize_bf16(
    prog: lacinfer.program,
    ins_names: list[str] = ["all"],
) -> None

把指定操作转换为 BF16。

lacinfer.quantize_fp8() [实验性]

lacinfer.quantize_fp8(
    prog: lacinfer.program,
    t: lacinfer.target,
    calibration: list[dict[str, lacinfer.argument]] = [],
) -> None

使用校准数据将 prog 原地量化为 FP8。每个校准样本都应是完整的程序输入映射,其参数名、类型和形状必须与程序输入匹配;目标 t 用于执行校准过程。

lacinfer.autocast_fp8() [实验性]

lacinfer.autocast_fp8(prog: lacinfer.program) -> None

原地把程序的 FP8 参数和返回值自动转换为 FP32,以便作为 LACInfer 程序的输入和输出使用。

程序持久化

lacinfer.load()

lacinfer.load(
    filename: str,
    format: str = "msgpack",
) -> lacinfer.program

从文件加载程序。format 支持 "msgpack" 和 "json"。

lacinfer.save()

lacinfer.save(
    p: lacinfer.program,
    filename: str,
    format: str = "msgpack",
) -> None

把程序保存到文件。

lacinfer.save_buffer()

lacinfer.save_buffer(p: lacinfer.program) -> bytes

把程序序列化为字节序列。

lacinfer.load_buffer()

lacinfer.load_buffer(b: bytes) -> lacinfer.program

从字节序列恢复程序。

已编译程序的可移植性受目标设备和软件版本影响。跨环境部署时应在目标环境验证加载与执行。

GPU 内存辅助函数

以下函数仅在启用 GPU 支持的构建中存在。

lacinfer.allocate_gpu()

lacinfer.allocate_gpu(
    s: lacinfer.shape,
    host: bool = False,
) -> lacinfer.argument

按指定形状分配内存。host=False 时分配 GPU 设备内存;host=True 时分配页锁定主机内存(Pinned Host Memory)2。

lacinfer.to_gpu()

lacinfer.to_gpu(
    arg: lacinfer.argument,
    host: bool = False,
) -> lacinfer.argument

把参数复制到 GPU 可用内存。

lacinfer.from_gpu()

lacinfer.from_gpu(arg: lacinfer.argument) -> lacinfer.argument

把 GPU 参数复制到主机可访问参数。

lacinfer.gpu_sync()

lacinfer.gpu_sync() -> None

等待 GPU 工作完成。

版本信息

lacinfer.__version__

lacinfer.__version__: str

扩展模块的版本字符串。

1. 这是 Python 通用的“仅限关键字参数”(keyword-only parameters)语法。参数列表中单独出现的 * 不是参数;其后的参数必须以 名称=值 的形式传入。 ↩
2. 页锁定主机内存位于系统内存中,其物理页不会被操作系统换出,适合 CPU 与 GPU 之间的高效数据传输;它不是 GPU 设备内存。 ↩
©龙芯开源社区 all right reserved,powered by Gitbook文档更新时间: 2026-09-30 13:16:32

results matching ""

    No results matching ""

    results matching ""

      No results matching ""