numba使用踩坑总结

由于没有完全理解numba就直接使用了,所以犯了一些使用时的错误。

  1. 尽量使用numpy的数据类型来写代码,numba对numpy的支持最好;但是并不是所有的numpy函数都被支持,比如我用到的np.clip, np.pad等函数都不支持,通过下面网址查看到底支持哪些numpy函数:http://numba.pydata.org/numba-doc/latest/reference/numpysupported.html。 遇到无法支持的函数时,两个选择,一个是重新手写该函数;另一个则是选择不在jit加速范围内调用该函数。

  2. np.zeros(shape, type)函数的调用中犯了一个错误,平时习惯性地会使用一个list作为shape参数,如[10, 10],平时正常使用numpy的时候也没问题,但是使用numba加速时却遇到了编译问题:

    Compilation is falling back to object mode WITHOUT looplifting enabled because Function "xxx" failed type inference due to: Invalid use of type(CPUDispatcher(<function xxx at 0x000001B6981D4708>)) with parameters (int64, int64, int64, array(float64, 4d, C))
    During: resolving callee type: type(CPUDispatcher(<function xxx at 0x000001B6981D4708>))
    

    numba的编译告警确实有点不太直观,从告警上很难定位到具体的问题出在哪儿,而且往往一个问题会引发出多处的告警。具体在定位的时候我喜欢用简化排除法,构造很简单的例子来排除问题,比如先把函数体变成空的,然后一点点加上内容,看问题到底出在哪里。

  3. 再来看一个类似的例子:https://github.com/numba/numba/issues/4650
    在numba的官方那里的一个issue,跟我上面的报错很类似。

    from numba import njit
    import numpy as np
    
    @njit
    def _get_most_similar(query_ftrs: np.ndarray, all_images_ftrs: np.ndarray) -> np.ndarray:
        products = np.empty(all_images_ftrs.shape[0], dtype=query_ftrs.dtype)
        for i in range(len(all_images_ftrs)):
            ftrs = all_images_ftrs[i]
            products[i] = np.dot(query_ftrs, ftrs)
    
    query_ftrs = np.zeros((1, 2048), dtype="float32")
    all_images_ftrs = np.zeros((18536, 2048), dtype="float32")
    
    _get_most_similar.py_func(query_ftrs, all_images_ftrs) # numpy is fine
    
    _get_most_similar(query_ftrs, all_images_ftrs) # numba is not
    

    报错信息如下:

    The error:
    numba.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
    Invalid use of Function() with argument(s) of type(s): (array(float64, 1d, C), int64, array(float32, 1d, C))
    

    官方人员给出了如下的定位过程:
    在这里插入图片描述
    总结下就是numba不能混用一个元素的list和单个scaler,但是numpy是可以的。这跟我那个问题的原因也很像,充分说明了numba对数据类型的要求很严格,推理地很严谨,不具有Numpy的兼容性。应该是tuple就别用list,应该是scaler也别用tuple(1,)。

  4. 再看一个类型问题:http://numba.pydata.org/numba-doc/latest/user/troubleshoot.html#my-code-doesn-t-compile
    是个官网文档上的例子。

  5. 若希望整个工程的numba都禁用,方便进行debug,可以使用修改环境变量的方法,注意如果在代码中去修改环境变量实测不可行,因为numba是依赖编译的,必须提前知道。也可以使用配置文件来保留配置设置。

    Numba 允许通过使用环境变量来改变其行为。除非另有说明,否则这些变量具有整数值且默认为零。 为方便起见,Numba
    还支持使用配置文件来保留配置设置。注意:要使用此功能,必须安装pyyaml。
    配置文件必须命名为.numba_config.yaml并存在于调用 Python
    解释器的目录中。在搜索环境变量之前,将读取配置文件(如果存在)以进行配置设置。这意味着环境变量设置将覆盖从配置文件获取的设置(配置文件用于设置永久首选项,而环境变量用于短暂首选项)。
    配置文件的格式是YAML格式的字典,它将下面的环境变量(没有NUMBA_前缀)映射到所需的值。例如,要永久打开开发人员模式(NUMBA_DEVELOPER_MODE环境变量)并控制流程图打印(NUMBA_DUMP_CFG环境变量),请创建一个包含以下内容的配置文件:

    developer_mode: 1
    dump_cfg: 1

    想关闭numba加速,则设置 disable_jit: 1 即可。
    参考:https://blog.youkuaiyun.com/wizardforcel/article/details/140061364

### 如何在 Pandas 中集成 Numba 提升性能 为了提升基于 Pandas 的数据分析流程,可以利用 Numba 来加速特定部分的执行效率。Numba 是一种即时编译器 (JIT),能够将 Python 函数转换成高效的机器码,在处理数值运算密集型任务时尤为有效。 #### 安装必要的库 首先需要确保环境中已经安装了 `numba` 和其依赖项: ```bash pip install numba ``` 对于希望进一步优化性能的情况,建议也安装 Cython 及其他推荐依赖组件[^2]。 #### 应用场景实例:使用 Numba 加速自定义聚合函数 当面对复杂的窗口操作或分组计算时,可以通过装饰器方式让 Numba 编译目标函数从而获得更好的表现效果。下面展示了一个简单的例子,说明怎样通过这种方式增强性能: ```python import pandas as pd from numba import jit # 假设有一个 DataFrame df 需要进行某些复杂计算 df = pd.DataFrame({ 'group': ['A', 'B'] * 5, 'value': range(10), }) @jit(nopython=True) # 启用 nopython 模式可以获得最佳性能 def custom_aggregate(values): """ 自定义聚合逻辑 """ result = sum(x ** 2 for x in values) return result / len(values) # 将上述函数应用于 groupby 聚合过程 result = df.groupby('group')['value'].apply(custom_aggregate).reset_index() print(result) ``` 此代码片段展示了如何编写并应用一个被 Numba JIT 编译过的自定义聚合函数到 Pandas 的 GroupBy 对象上。注意这里启用了 `nopython=True` 参数以确保尽可能高的编译质量[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值