Bug——PaddleX人脸识别报错:Process finished with exit code -1073741819 (0xC0000005)

一、问题1

复制代码
from PaddleX.paddlex import create_pipeline
pipeline_ = create_pipeline(pipeline="face_recognition", device="gpu")
index_file_path = "./face_index/vector.index"
if os.path.exists(index_file_path):
    print("加载已有的索引")
    index_data = "face_index
else:
    print("索引文件不存在,构建索引")
    index_data = pipeline_.build_index(gallery_imgs="face_demo_gallery", gallery_label="face_demo_gallery.txt")
    index_data.save("face_index")  # 会在face_recognition产生face_index/id_map.yaml

在执行构建索引这一步的时候报错了

Using official model (PP-YOLOE_plus-S_face), the model files will be automatically downloaded and saved in C:\Users\guan.linyi\.paddlex\official_model

信息: 用提供的模式无法找到文件。

Process finished with exit code -1073741819 (0xC0000005)

1.1、问题分析

1、先去把最新版本的PaddleX源码拉下来,截止2025年9月30日,最新版本是3.2

https://github.com/PaddlePaddle/PaddleX/tree/release/3.2?tab=readme-ov-file

这样做的目的是希望新版本的代码已经解决了这个bug

2、拉下来再试了一下。还是报同样的错误。这时候考虑错误产生的原因,原因可能是来自三个方面:系统问题、数据问题、代码问题、环境问题,已经通过拉取最新代码,那么代码问题的可能性很小,看起来也不像是系统问题,数据是用的官网的demo数据,应该不是数据问题。

那大概率是环境问题。

对于环境问题,已经按照下面官网的方式安装了PaddlePaddle和paddlex

python 复制代码
1.先安装PaddlePaddle:
# https://paddlepaddle.github.io/PaddleX/latest/installation/paddlepaddle_install.html#docker

# CPU 版本
python -m pip install paddlepaddle==3.0.0 -i https://www.paddlepaddle.org.cn/packages/stable/cpu/

# GPU 版本,需显卡驱动程序版本 ≥450.80.02(Linux)或 ≥452.39(Windows)
 python -m pip install paddlepaddle-gpu==3.0.0 -i https://www.paddlepaddle.org.cn/packages/stable/cu118/

# GPU 版本,需显卡驱动程序版本 ≥550.54.14(Linux)或 ≥550.54.14(Windows)
 python -m pip install paddlepaddle-gpu==3.0.0 -i https://www.paddlepaddle.org.cn/packages/stable/cu126/

内网环境:
pip install paddlepaddle_gpu-3.0.0rc0-cp310-cp310-win_amd64.whl

2.再安装paddlex
# https://paddlepaddle.github.io/PaddleX/latest/installation/installation.html#1
pip install paddlex  
内网环境:
拉取paddlex3.2源码PaddleX,再进入PaddleX目录,pip install -e .

结果还是报错。

3、这种情况下,我们应该想办法追踪到程序是在哪个文件哪行代码报错停止的。于是开启了debug之后发现

paddlex/inference/pipelines/components/faisser.py

python 复制代码
@class_requires_deps("faiss-cpu")
class FaissBuilder:
    @classmethod
    def build(
        cls,
        gallery_imgs,
        gallery_label,
        predict_func,
        metric_type="IP",
        index_type="HNSW32",
    ):
        assert (
            index_type in cls.SUPPORT_INDEX_TYPE
        ), f"Supported index types only: {cls.SUPPORT_INDEX_TYPE}!"

        assert (
            metric_type in cls.SUPPORT_METRIC_TYPE
        ), f"Supported metric types only: {cls.SUPPORT_METRIC_TYPE}!"

        if isinstance(gallery_label, str):
            gallery_docs, gallery_list = cls.load_gallery(gallery_label, gallery_imgs)
        else:
            gallery_docs, gallery_list = gallery_label, gallery_imgs

        # 这里获取特征
        features = [res["feature"] for res in predict_func(gallery_list)]
        dtype = np.uint8 if metric_type in cls.BINARY_METRIC_TYPE else np.float32
        features = np.array(features).astype(dtype)
        vector_num, vector_dim = features.shape

        if metric_type in cls.BINARY_METRIC_TYPE:
            index = faiss.index_binary_factory(
                vector_dim,
                cls._get_index_type(metric_type, index_type, vector_num),
                cls._get_metric_type(metric_type),
            )
        else:
            index = faiss.index_factory(
                vector_dim,
                cls._get_index_type(metric_type, index_type, vector_num),
                cls._get_metric_type(metric_type),
            )
            index = faiss.IndexIDMap2(index)
        ids = {}

        # calculate id for new data
        index, ids = cls._add_gallery(
            metric_type, index, ids, features, gallery_docs, mode="new"
        )
        return IndexData(
            index, {"id_map": ids, "metric_type": metric_type, "index_type": index_type}
        )

dtype = np.uint8 if metric_type in cls.BINARY_METRIC_TYPE else np.float32

features = np.array(features).astype(dtype)

vector_num, vector_dim = features.shape

这个features是个list,list的长度就是记忆库里面的图片数,比如245,每个特征向量维度是512

然后会变成(245,512)

出错的地方是这里:

python 复制代码
# calculate id for new data
index, ids = cls._add_gallery(
        metric_type, index, ids, features, gallery_docs, mode="new"
)

@classmethod
def _add_gallery(
        cls, metric_type, index, ids, gallery_features, gallery_docs, mode
    ):
    start_id = max(ids.keys()) + 1 if ids else 0
    ids_now = (np.arange(0, len(gallery_docs)) + start_id).astype(np.int64)

    # only train when new index file
    if mode == "new":
    if metric_type in cls.BINARY_METRIC_TYPE:
        index.add(gallery_features)
    else:
        index.train(gallery_features)

    if metric_type not in cls.BINARY_METRIC_TYPE:
        index.add_with_ids(gallery_features, ids_now)  # 这句报错
    # TODO(gaotingquan): how append when using hamming metric type
    # else:
    #   pass

    for i, d in zip(list(ids_now), gallery_docs):
        ids[i] = d
    return index, ids

运行到index.add_with_ids(gallery_features, ids_now) # 这句报错

swig/python detected a memory leak of type 'std::unordered_map< long long,long long > *', no destructor found.

swig/python detected a memory leak of type 'std::unordered_map< long long,long long > *', no destructor found.

index.add_with_ids(gallery_features, ids_now)这句会进入

python 复制代码
D:\miniforge3\envs\stranger_win_env\Lib\site-packages\faiss

class IndexIDMap2(IndexIDMap):

    def add_with_ids(self, n, x, xids):
        return _swigfaiss_avx2.IndexIDMap2_add_with_ids(sellf, n, x, xids)

1.2 直接原因分析

不是 Python 本身的问题 ,而是 FAISS 的 Python 接口(SWIG 封装) 在调用 add_with_ids 时,内部使用了 std::unordered_map<long long, long long>,但 没有正确释放内存 ,导致 内存泄漏警告

FAISS 的 Index::add_with_ids() 方法在内部会构造一个 id_map,但 SWIG 没有为这个 map 提供析构函数,所以 Python 无法释放它,导致泄漏警告。

1.3 解决方法

直接去https://pypi.org/project/faiss-cpu/1.12.0/#history ,安装最新版本的

pip install faiss-cpu==1.12.0

这实际上是内网环境导致的坑,内网环境的源比较落后,所以不能安装最新版本的库,这导致如果你某些库去pypi找whl装最新的,就会跟另一些旧的库不兼容,但如果你找旧库去兼容旧库,你最好祈祷那些旧库是没有bug的,如果旧库是有bug的,就会像现在这样,被迫去找最新的库解决旧库的bug,那么这时候你最好祈祷新的库跟你其他旧的库是兼容的,否则你装不了新的库,还好,这个库装最新的是兼容的。或许存在直接手动解决旧库bug的方法,但是这里没有去尝试,因为说实在的,新库常常修复了很多bug,自己修bug太难太麻烦了。

二、问题2

2.1 问题分析

paddlex3.2 居然要联网才能推理,原先是这样推理的:

python 复制代码
# https://paddlepaddle.github.io/PaddleX/latest/pipeline_usage/tutorials/cv_pipelines/face_recognition.html#222-python

from paddlex import create_pipeline

pipeline = create_pipeline(pipeline="face_recognition")

index_data = pipeline.build_index(gallery_imgs="face_demo_gallery", gallery_label="face_demo_gallery/gallery.txt")
index_data.save("face_index")

output = pipeline.predict("friends1.jpg", index=index_data)
for res in output:
    res.print()
    res.save_to_img("./output/")
    res.save_to_json("./output/")

2.2 解决方法

我们把pipeline改成读取本地的配置文件:

python 复制代码
# https://paddlepaddle.github.io/PaddleX/latest/pipeline_usage/tutorials/cv_pipelines/face_recognition.html#222-python

from paddlex import create_pipeline

pipeline = create_pipeline(pipeline=r"D:\zero_track\mem_and_mat\PaddleX\paddlex\configs\pipelines\face_recognition.yaml", device="gpu")

index_data = pipeline.build_index(gallery_imgs="face_demo_gallery", gallery_label="face_demo_gallery/gallery.txt")
index_data.save("face_index")

output = pipeline.predict(r"D:\zero_track\mem_and_mat\face_demo_gallery\test_images\friends1.jpg", index=index_data)
for res in output:
    res.print()
    res.save_to_img("./output/")
    res.save_to_json("./output/")

没想到又报了一个读取字体要联网的

Connecting to https://paddle-model-ecology.bj.bc

ebos.com/paddlex/PaddleX3.0/fonts/PingFang-SC-Regular.ttf ...

找到D:\zero_track\mem_and_mat\PaddleX\paddlex\utils\fonts.py

把PINGFANG_FONT那行注释了,改成自己的local_path,自己的字体是Github上找的下载下来的

PINGFANG_FONT = Font(font_name="MSYH.TTC", local_path=r"D:\zero_track\mem_and_mat\fonts\MSYH.TTC")

三、总结

内网装环境是个坑。

相关推荐
less is more_09303 小时前
风力发电机输出功率模型综述
笔记·学习·数学建模
丰锋ff3 小时前
2006 年真题配套词汇单词笔记(考研真相)
笔记·学习·考研
早睡冠军候选人6 小时前
K8s学习----节点(Node)
运维·学习·云原生·容器·kubernetes
小林up11 小时前
《Unity Shader入门精要》学习1:Phong 模型中法向量归一化的正确位置
学习·unity·游戏引擎
Lojarro11 小时前
GO学习2:基本数据类型 与 转换
后端·学习·golang
come1123412 小时前
冀教版三年级上册英语-学习思路和引导方法
学习
派森先生12 小时前
sk07.【scikit-learn基础】--『监督学习』之支持向量机
学习·支持向量机·scikit-learn
wdfk_prog13 小时前
`git rm --cached`:如何让文件“脱离”版本控制
大数据·linux·c语言·笔记·git·学习·elasticsearch
lingliang13 小时前
机器学习之三大学习范式:监督学习、无监督学习、强化学习
人工智能·学习·机器学习