资讯动态

MLX 数据类型(Dtype)完全指南:支持的类型、层级体系与精度控制

发布时间:2026/9/11 1:11:13 来源:尧图企业网站定制
MLX 数据类型Dtype完全指南支持的类型、层级体系与精度控制【免费下载链接】mlxMLX: An array framework for Apple silicon项目地址: https://gitcode.com/GitHub_Trending/ml/mlx导读在 MLXApple silicon 上的数组框架中数据类型Data Type简称 dtype决定了数组元素的位宽、取值范围与计算精度。本文以官方文档 docs/src/python/data_types.rst 为主体结合 mlx/dtype.h、mlx/dtype.cpp 等核心源码系统梳理 MLX 支持的 14 种数据类型、默认类型约定、float64 的 CPU 限制、DtypeCategory层级体系以及issubdtype/finfo/iinfo等工具函数。读完本文你将能在 MLX 中正确选择与转换数据类型、判断类型归属并理解类型提升type promotion的底层规则。默认数据类型MLX 的默认浮点类型是float32默认整数类型是int32。这意味着直接用 Python 标量创建数组时浮点字面量默认被解释为float32整数字面量默认被解释为int32大多数运算如mlx.core.add在没有显式指定输出类型时遵循类型提升规则得到结果类型与 NumPy 的默认float64/int64不同MLX 选择 32 位精度作为默认值这与 Apple silicon 上 GPU 的原生计算能力相匹配可在精度与性能之间取得平衡。int32同时是大多数索引、切片和形状相关操作的基础类型这一约定贯穿整个框架。MLX 支持的 14 种数据类型官方文档给出的Dtype取值表如下字段含义Type 为类型名Bytes 为每个元素占用的字节数Description 为简要说明TypeBytesDescriptionbool_1布尔True/False数据类型uint818 位无符号整数uint16216 位无符号整数uint32432 位无符号整数uint64864 位无符号整数int818 位有符号整数int16216 位有符号整数int32432 位有符号整数int64864 位有符号整数bfloat16216 位脑浮点e8, m7float16216 位 IEEE 浮点e5, m10float32432 位浮点float64864 位双精度complex64864 位复数浮点从源码确认类型全集在 mlx/dtype.h 中Dtype结构体的Val枚举恰好列出了上述 14 种类型且每个类型常量在 mlx/dtype.h 中被定义为inline constexpr全局常量如float16占sizeof(uint16_t)即 2 字节complex64占sizeof(complex64_t)即 8 字节字节数与文档表格完全一致。值得注意的几个类型特征bfloat16脑浮点指数占 8 位e8、尾数占 7 位m7与float32拥有相同的指数范围因此动态范围大、但精度较低它是 MLX 中模型训练/推理最常用的低精度类型之一。float16IEEE 半精度指数占 5 位e5、尾数占 10 位m10与float32的动态范围有明显差异需注意溢出问题。complex64由两个 32 位浮点构成实部与虚部用于 FFT 等复数运算参见 docs/src/python/fft.rst。float64 的 GPU 限制官方文档明确给出如下约束类型为float64的数组只能在 CPU 上执行运算。在 GPU 上使用float64数组会抛出异常。这是因为 Apple silicon 的 GPUMetal 后端原生并不支持双精度运算MLX 仅在 CPU 后端mlx/backend/cpu为float64提供完整实现。因此在编写代码时若需要高精度数值计算如数值稳定的矩阵分解、科学计算请在 CPU 上使用float64若目标设备是 GPU请将数据显式转换为float32或float16/bfloat16机器学习训练与推理场景通常使用float32或bfloat16一般不需要float64。Dtype 的 Kind 分类Dtype内部还通过Kind枚举对类型进行第一级分类见 mlx/dtype.h它直接决定了类型提升时的行为分组Kind含义覆盖类型b布尔bool_u无符号整数uint8/uint16/uint32/uint64i有符号整数int8/int16/int32/int64f浮点float16/float32/float64/bfloat16c复数complex64Vvoid特殊标记用于bfloat16的兼容处理在 mlx/dtype.cpp 的type_kinds数组中可以看到bfloat16被标记为Vvoid这是 MLX 对非 IEEE 浮点类型的内部处理方式。类型层级体系DtypeCategory数据类型按类别Category组织成一个层级体系hierarchy。官方文档指出数据类型按照层级排列。更多信息参见DtypeCategory对象文档。使用issubdtype判断一个dtype或类别是否是另一个类别的子类型。完整的层级树如下该结构定义于 Python 绑定 python/src/array.cpp 的DtypeCategory文档字符串中generic ├── bool_ └── number ├── integer │ ├── unsignedinteger │ │ ├── uint8 │ │ ├── uint16 │ │ ├── uint32 │ │ └── uint64 │ └── signedinteger │ ├── int8 │ ├── int16 │ ├── int32 │ └── int64 └── inexact ├── floating │ ├── float16 │ ├── bfloat16 │ ├── float32 │ └── float64 └── complexfloating └── complex64即共 8 个类别generic、number、integer、signedinteger、unsignedinteger、inexact、floating、complexfloating。在 Python 侧通过mx.DtypeCategory类型访问类别常量直接暴露在mlx.core命名空间中如mx.floating、mx.integer。这一层级关系在 C 侧由 mlx/dtype.cpp 的subcategory_to_category布尔矩阵定义例如floating是inexact、number、generic的子类型但不是complexfloating的子类型integer是number、generic的子类型但不是inexact的子类型。使用 issubdtype 判断类型归属issubdtype(arg1, arg2)用于判断第一个 dtype或类别是否是第二个 dtype或类别的子类型。它接受Dtype与DtypeCategory的任意组合参见 python/src/ops.cpp 的绑定与示例。官方文档给出的典型用法示例import mlx.core as mx ints mx.array([1, 2, 3]) # dtype 为 int32 floats mx.array([1.0, 2.0]) # dtype 为 float32 # dtype 与类别混合判断 mx.issubdtype(ints.dtype, mx.integer) # True mx.issubdtype(ints.dtype, mx.floating) # False mx.issubdtype(floats.dtype, mx.integer) # False mx.issubdtype(floats.dtype, mx.floating) # True # dtype 与 dtype 判断仅相同类型为 True mx.issubdtype(mx.float64, mx.float32) # False mx.issubdtype(mx.float32, mx.float64) # False # dtype 与类别 mx.issubdtype(mx.float64, mx.floating) # True mx.issubdtype(mx.float32, mx.floating) # True # 类别之间的包含关系 mx.issubdtype(mx.float32, mx.inexact) # True mx.issubdtype(mx.signedinteger, mx.floating) # False底层实现mlx/dtype.cpp规则如下issubdtype(dtype_a, dtype_b)仅当两者完全相等时返回True单个 dtype 只包含它自己issubdtype(dtype, category)先通过type_to_category表mlx/dtype.cpp将 dtype 映射到其所属类别再查subcategory_to_category矩阵issubdtype(category_a, category_b)直接查subcategory_to_category矩阵。该行为与 NumPy 逐类型对齐——python/tests/test_ops.py 的test_issubdtype测试将 MLX 与 NumPy 在 20 种类型/类别的笛卡尔积上逐一比对确保二者判定结果完全一致。类型提升Type Promotion规则两个不同 dtype 的数组参与运算时结果类型由类型提升规则决定。MLX 遵循JAX 的类型提升规则源码注释明确标注见 mlx/dtype.cpp核心实现是 mlx/dtype.cpp 中 14×14 的type_rules查找表由promote_types(t1, t2)mlx/dtype.cpp查表返回。要点归纳整数提升两个无符号整数提升到较大的那个有符号与无符号混合时提升到能容纳两者的有符号类型如uint8与int8提升为int16整数 浮点提升为浮点类型如int64与uint64提升为float32int64与float16提升为float16半精度优先任何浮点与float16/bfloat16混合时结果保持在低精度浮点如float16与int64提升为float16float32与bfloat16二者相互提升为float32注意float16与bfloat16提升也为float32float64主导float64与任何其他类型混合时提升为float64complex64主导complex64与任何类型混合时提升为complex64。promote_types同样暴露在 Python 侧可用于显式查询两个 dtype 的运算结果类型。finfo 与 iinfo查询类型的数值极限finfo和iinfo用于查询浮点类型与整数类型的数值属性其 Python 绑定定义于 python/src/array.cpp。finfo浮点类型信息mx.finfo(dtype)接受float16/bfloat16/float32/float64/complex64返回包含以下字段的对象属性含义bits该类型占用的位数min可表示的最小最负数值max可表示的最大数值eps1.0 与比 1.0 大的下一个可表示数之差smallest_normal最小的正规格化数dtype对应的 Dtype实现位于 mlx/utils.cppfinfo构造函数会首先校验传入类型必须属于inexact类别否则抛出invalid_argument异常complex64会映射到float32的极限值。例如import mlx.core as mx info mx.finfo(mx.bfloat16) info.bits # 16 info.eps info.max info.smallest_normal框架内部也大量使用finfo如 mlx/fast.cpp 用finfo(scores.dtype()).min作为注意力掩码的填充值、mlx/linalg.cpp 用finfo(a.dtype()).eps计算矩阵分解的截断阈值rcond。iinfo整数类型信息mx.iinfo(dtype)接受所有 8 种整数类型返回包含min、max、dtype字段的对象mlx/utils.cpp 通过dispatch_int_types按类型分派numeric_limitsimport mlx.core as mx info mx.iinfo(mx.int32) info.min # -2147483648 info.max # 2147483647实践建议默认选择日常计算使用默认的float32/int32无需显式指定 dtype低精度加速深度学习训练与推理优先使用bfloat16动态范围大或float16可通过array.astype()或mx.array(..., dtype...)转换精度敏感场景在 CPU 上使用float64并避免将其送入 GPU 运算类型判断需要根据数组类型分支时用mx.issubdtype(arr.dtype, mx.floating)而非逐一比较数值极限实现 softmax、masked attention、rcond 等需要极小值/ε 的算法时用mx.finfo/mx.iinfo动态获取避免硬编码常量。延伸阅读官方数据类型文档docs/src/python/data_types.rstDtype 核心定义mlx/dtype.h、mlx/dtype.cpp类型字符串转换mlx/dtype_utils.cppPython 绑定DtypeCategory、finfo、iinfopython/src/array.cppissubdtype 绑定与示例python/src/ops.cpp类型系统测试与 NumPy 对齐验证python/tests/test_ops.py【免费下载链接】mlxMLX: An array framework for Apple silicon项目地址: https://gitcode.com/GitHub_Trending/ml/mlx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价