5.1 适配参数精度(8bit整数)
在实际问题的求解中,量子硬件平台对参数精度存在较为严格的限制,如相干伊辛机CIM仅支持8位整数范围
当用户构建QUBO模型时,需特别关注以下两个核心环节:首先,模型转换过程必须保证Ising矩阵的系数严格落在硬件支持的动态范围内;其次,针对不同问题特性,需要灵活选择精度适配策略(如动态范围压缩或变量拆分)。本节提供了四种使用Kaiwu SDK降精度的参考方案。需要强调的是,最优方法往往取决于具体问题的矩阵特性——对于元素差异较小的稀疏矩阵,直接缩放取整可能已足够;而对于存在极端值的密集矩阵,则需采用更精细的变量拆分技术。
通过本节内容学习,在面对8位精度的硬件限制,各位开发者可充分利用QUBO模型的建模优势,最终转化为符合量子计算硬件要求的Ising模型。
1. 背景介绍

如上图所示,因为QUBO模型只是数学模型,Ising模型是贴近物理实现的模型,所以在使用CIM进行计算时,无论使用的是QUBO模型,还是Ising模型,都会被转换为Ising模型进行真机求解。因此,前文提到的8位整数范围的精度限制,是对Ising模型的精度限制,而非对QUBO模型的限制。为了更好地检查如何限制QUBO矩阵,使得建模符合精度限制,下面将讲解QUBO转化为Ising模型的方法,并介绍这样限制的原因。
1.1 如何QUBO转Ising?
本节介绍QUBO如何转化为Ising模型,以便于理解动态范围检查如何限制QUBO矩阵。
QUBO模型的哈密顿量表示为:
其中
Ising模型的变量定义为:自旋变量
其中
为了将QUBO模型映射到Ising模型,需进行变量替换。令
由此可得Ising模型的系数:
上式中的一次项通过添加辅助变量
注意:QUBO变量满足
以一个简单的QUBO模型为例:
经过变换之后的Ising模型为:
1.2 为什么要降精度为8bit?
在计算机科学和数字硬件设计中,八位整数(8-bit Integer)是指用8个二进制位(bit)存储的整数。我们所讲的8位整数的取值范围为有符号整数情况下的,最小负数为-128(10000000),最大正数为127(01111111)。
在使用CIM进行计算时,采用8位整数范围(即
2. Kaiwu SDK降低精度的方法
Kaiwu SDK提供了四种降低参数精度的方法,分别是直接截断(adjust_ising_matrix_precision
)、 动态范围压缩(perform_precision_adaption_mutate
)、变量拆分(perform_precision_adaption_split
)以及整合了适应性截断和变量拆分的降低精度装饰类(PrecisionReducer
):
- 直接截断方法最简单方便,但是若存在极端值会导致严重的精度损失;
- 动态范围压缩方法在修改矩阵的同时能够保持矩阵的解不变,但能够改变精度的程度取决于矩阵本身的可下降空间;
- 变量拆分方法能够将矩阵修改到任意精度,但是新矩阵的比特数随着精度变化量增长较快。
2.1 方法一:直接截断(adjust_ising_matrix_precision
)
直接取整法是最简单的精度调整方案,其实现原理是将矩阵元素全部线性缩放到目标位宽(如8位整型范围-128~127),再执行四舍五入取整。该方法可以通过kaiwu.ising.adjust_ising_matrix_precision
或kaiwu.qubo.adjust_qubo_matrix_precision
函数实现。
如下表所示,kaiwu.ising.adjust_ising_matrix_precision
是用于调整Ising矩阵精度的直接取整法函数,而kaiwu.qubo.adjust_qubo_matrix_precision
能够将QUBO矩阵转换为Ising矩阵,在用直接取整法调整完生成的Ising矩阵的精度后,再将矩阵变为QUBO矩阵的形式输出。
函数 | kaiwu.ising.adjust_ising_matrix_precision | kaiwu.qubo.adjust_qubo_matrix_precision |
---|---|---|
输入 | Ising矩阵 | QUBO矩阵 |
方法 | 直接取整法 | 直接取整法 |
流程 | Ising矩阵>>>调节后的Ising矩阵 | QUBO矩阵>>>对应的Ising矩阵>>>调节后的Ising矩阵>>>调节后对应的QUBO矩阵 |
输出 | 调节后的Ising矩阵 | 调节后的QUBO矩阵 |
示例代码如下:
import numpy as np
import kaiwu as kw
# 原始矩阵包含微小差异项
ori_ising_mat1 = np.array([[0, 0.22, 0.198],
[0.22, 0, 0.197],
[0.198, 0.197, 0]])
ising_mat1 = kw.preprocess.adjust_ising_matrix_precision(ori_ising_mat1)
print("调整后矩阵:\n", ising_mat1)
调整前后矩阵的对比如下:
必须注意,该方法对元素间差异较小的矩阵效果较好,但当矩阵存在极端值时,直接取整会导致严重精度损失。例如对于存在极端值的矩阵:
# 包含极端值的矩阵
ori_ising_mat2 = np.array([[0, 0.22, 0.198],
[0.22, 0, 50],
[0.198, 50, 0]])
ising_mat2 = kw.preprocess.adjust_ising_matrix_precision(ori_ising_mat2)
print("极端值调整后矩阵:\n", ising_mat2)
输出结果为:
此时,微小项0.22和0.198都被压缩为1,而极端值50被放大到127,但是两者的相对比值由于精度上限(127)以及整数的限制(1)而被扭曲,导致求解结果偏离真实最优解。因此,直接取整法仅推荐在动态范围较小的场景下使用。对于复杂问题,应优先选择下面将要讲到的动态范围压缩或变量拆分方案。
2.2 方法二:动态范围压缩(perform_precision_adaption_mutate
)
动态范围(Dynamic Range, DR) 是衡量矩阵系数分布的关键指标,适用于QUBO矩阵和Ising矩阵,通过减小动态范围,可以降低原矩阵所需要的参数精度。
动态范围定义为:
其中,
通过矩阵元素重缩放与四舍五入操作,将原始矩阵
具体步骤为:首先,设缩放因子为
缩放因子需满足:
此时变换后的矩阵满足
理论证明,当
(其中
Kaiwu SDK主要使用函数perform_precision_adaption_mutate
进行动态范围压缩。以下矩阵为例:
经过perform_precision_adaption_mutate
处理后,动态范围从
详细代码如下:
import kaiwu as kw
import numpy as np
# 原始QUBO矩阵
mat0 = np.array([[0, -20, 0, 40, 1.1],
[0, 0, 12240, 1, 120],
[0, 0, 0, 0, -10240],
[0, 0, 0, 0, 2.05],
[0, 0, 0, 0, 0]])
# 执行mutate方法降低精度
mutated_mat = kw.preprocess.perform_precision_adaption_mutate(mat0)
print("调整后矩阵:\n", mutated_mat)
运行该程序,得到调整后的矩阵为:
2.3 方法三:变量拆分(perform_precision_adaption_split
)
由于当前量子计算机对Ising系数的存储方式为定点数,且只有8位精度,对于最大最小值的比值超过
设目标函数为:
对于满足
拆分的方式将
例如,对于
import kaiwu as kw
import numpy as np
mat = np.array([[0, -15,0, 40],
[-15,0, 0, 1],
[0, 0, 0, 0],
[40, 1, 0, 0]])
splitted_ret, last_idx = kw.preprocess.perform_precision_adaption_split(mat, 4)
print(splitted_ret)
min_increment
计算得到默认值为1,精度设置为4个比特,范围在

如图所示,红色的箭头指示出拆分前后的对应关系,蓝色框中的数字则是用于限制新建的变量的值保持一致的惩罚项,通过这样拆分变量,可以在保持原矩阵的解的情况下,将参数精度降低。降低精度的过程通过param_bit
,min_increment
,penalty
,round_to_increment
等参数来调节。
其中,min_increment
(最小步长)参数用于降低元素精度,同时保持原始数据的相对差异。该参数使矩阵的值满足min_increment
的整数倍(如min_increment=0.5
时,元素只能为 0, 0.5, 1.0 等),其默认值为自动计算矩阵元素间的最小正差值(如矩阵中有 0.1 和 0.3,则默认min_increment=0.2
)。
round_to_increment
(舍入策略)参数为了使得调整元素时,确保所有元素之和严格等于原值。例如,不启用reduce_error
时,15将被拆分成7.5+7.5,若分别近似取整会变成8+8,总和发生偏离(15 → 16)。启用reduce_error=True
后,通过动态调整部分元素的舍入方向( 7.5 → 7 或 8),使总和严格等于原值(如 15 → 7+8=15)。
演示代码如下:
splitted_ret2, last_idx2 = kw.preprocess.perform_precision_adaption_split(mat, 4, min_increment=3, round_to_increment=True)
print(splitted_ret2)
结果为:
对拆分后精度满足要求的矩阵进行求解后,可以通过restore_splitted_solution
函数将其恢复成原矩阵的解。
worker = kw.cim.CIMOptimizer(iterations=1000)
output = worker.solve(ising_mat)
opt = kw.sampler.optimal_sampler(ising_mat, output, bias=0, negtail_ff=False)
sol = opt[0][0]
org_sol = kw.preprocess.restore_split_solution(sol, last_idx)
print(org_sol)
结果为:
2.4 方法四:降低精度装饰类(PrecisionReducer
)
降低精度装饰类(PrecisionReducer
)是Kaiwu SDK中一种智能化的精度适配方案,其核心思想是:通过适应性截断与变量拆分的组合策略,将原始矩阵参数适配到硬件支持的精度范围内。该方案以装饰器模式实现,用户可将任意优化器(如模拟退火、量子退火等)作为基础组件传入,PrecisionReducer
会在求解过程中自动完成矩阵精度调整,同时保证解的可行性。
装饰类的工作原理分为两个阶段:适应性截断与变量拆分决策。当用户设定目标精度(precision
参数)后,装饰类首先计算矩阵的动态范围,若动态范围超过硬件限制(由target_bits
参数控制),则优先尝试通过一定程度上的适应性截断降低动态范围;若截断后仍无法满足精度要求,则自动触发变量拆分操作,将大系数项分解为多个等效变量,并通过惩罚项约束其等价性。整个过程可通过日志系统追踪,详细示例代码如下:
import kaiwu as kw
# 启用详细日志输出
kw.utils.set_log_level("INFO")
# 定义原始Ising矩阵
matrix = -np.array([[ 0. , 1.23 , 0. , 1. , 1. ],
[ 1.23 , 0. , 0. , 1., 1. ],
[ 0. , 0. , 0. , 1., 1. ],
[ 1. , 1., 1. , 0. , 1. ],
[ 1. , 1., 1. , 1. , 0. ]])
# 创建基础优化器(模拟退火)
base_optimizer = kw.classical.SimulatedAnnealingOptimizer(
initial_temperature=100,
alpha=0.99,
cutoff_temperature=0.001,
iterations_per_t=10,
size_limit=5
)
# 添加精度降级装饰器(目标精度8位)
precision_optimizer = kw.cim.PrecisionReducer(base_optimizer, precision=8)
# 执行求解
solution = precision_optimizer.solve(matrix)
装饰类的核心参数only_feasible_solution
控制解的可行性验证。当设为True
时,装饰类会过滤所有违反拆分约束的解(通过惩罚项判断),若所有解均不可行则抛出异常;当设为False
时,允许返回非可行解(可能存在拆分变量不一致的情况)。对于工业级应用,建议保持only_feasible_solution=True
以确保解的物理意义。