atlas 模型推理
收藏回复举报
atlas 模型推理
新人帖
发表于2023-01-06 14:25:19
0 查看

本文验证的模型是yolov5s模型,训练好对应的best.pt后,通过yolov5 对应的export.py文件将模型转换成onnx格式:

python export.py --weights best.pt --include ONNX

硬件平台是昇腾-310,host模式,通过atc工具将best.onnx转换成指定的格式:

atc --model best.onnx --framework 5 --output best.om --soc_version Ascend310

模型初始化推理:

STATUS SampleDetector::InitModel(const std::string &strModelName)

{

    SDKLOG(INFO) << "load model " << strModelName;

    auto ret = aclmdlQuerySize(strModelName.c_str(), &mModelMSize, &mModelWSize);

    ret = aclrtMalloc(&mModelMptr, mModelMSize, ACL_MEM_MALLOC_HUGE_FIRST);

    ret = aclrtMalloc(&mModelWptr, mModelWSize, ACL_MEM_MALLOC_HUGE_FIRST);

    ret = aclmdlLoadFromFileWithMem(strModelName.c_str(), &mModelID, mModelMptr,mModelMSize, mModelWptr, mModelWSize);

    mModelDescPtr = aclmdlCreateDesc();

    ret = aclmdlGetDesc(mModelDescPtr, mModelID);

    // 创建模型输出的数据集结构

    mInputDatasetPtr = aclmdlCreateDataset();

    mOutputDatasetPtr = aclmdlCreateDataset();

    //获取模型的输入个数,为输入分配内存并创建输出数据集

    int iModelInputNum = aclmdlGetNumInputs(mModelDescPtr);

    SDKLOG(INFO) << "num of inputs " << iModelInputNum;

    {

    aclmdlGetInputDims(mModelDescPtr, 0, &m_input_dims);

    SDKLOG(INFO) << "input dim is : "<< m_input_dims.dims[0] << " " << m_input_dims.dims[1] << " " << m_input_dims.dims[2] << " " << m_input_dims.dims[3];

    size_t buffer_size = aclmdlGetInputSizeByIndex(mModelDescPtr, 0);

    mModelInputSize.width =  m_input_dims.dims[2];

    mModelInputSize.height =  m_input_dims.dims[3];

    ret = aclrtMalloc(&m_input_buffer, aclmdlGetInputSizeByIndex(mModelDescPtr, 0), ACL_MEM_MALLOC_NORMAL_ONLY);

    m_input_data_buffer = aclCreateDataBuffer(m_input_buffer, buffer_size);

    ret = aclmdlAddDatasetBuffer(mInputDatasetPtr, m_input_data_buffer);

    }





    //获取模型的输出个数,为输出分配内存并创建输出数据集

    mModelOutputNums = aclmdlGetNumOutputs(mModelDescPtr);

    SDKLOG(INFO) << "num of outputs " << mModelOutputNums;

    {

    size_t buffer_size = aclmdlGetOutputSizeByIndex(mModelDescPtr, 0);

    aclmdlGetOutputDims(mModelDescPtr, 0, &m_output_dims);

    SDKLOG(INFO) << "output dims is : " << m_output_dims.dims[0] << " " << m_output_dims.dims[1] << " " << m_output_dims.dims[2] << " " << m_output_dims.dims[3];

    if(mAclRunMode == ACL_HOST) m_output_buffer_host= new char[aclmdlGetOutputSizeByIndex(mModelDescPtr, 0)]();

    ret = aclrtMalloc(&m_output_buffer, buffer_size, ACL_MEM_MALLOC_NORMAL_ONLY);

    m_output_data_buffer = aclCreateDataBuffer(m_output_buffer, buffer_size);

    ret = aclmdlAddDatasetBuffer(mOutputDatasetPtr, m_output_data_buffer);

    }

    aclrtGetRunMode(&mAclRunMode);

    if(mAclRunMode == ACL_DEVICE)

    {

        SDKLOG(INFO) << "run in device mode";

    }

    else

    {

        SDKLOG(INFO) << "run in host mode";

    }

    //预处理功能

    if(mAclRunMode == ACL_DEVICE)

    {

        size_t single_chn_size = m_input_dims.dims[0] * m_input_dims.dims[2] * m_input_dims.dims[3] * sizeof(float);

        m_chw_wrappers.emplace_back(m_input_dims.dims[2], m_input_dims.dims[3], CV_32FC1, m_input_buffer);

        m_chw_wrappers.emplace_back(m_input_dims.dims[2], m_input_dims.dims[3], CV_32FC1, m_input_buffer + single_chn_size);

        m_chw_wrappers.emplace_back(m_input_dims.dims[2], m_input_dims.dims[3], CV_32FC1, m_input_buffer + 2 * single_chn_size);

    }

    return STATUS_SUCCESS;

}

STATUS SampleDetector::Detect(const cv::Mat &inFrame, std::vector<BoxInfo> &result, float thresh)

{

    // set current context

    auto ret = aclrtSetCurrentContext(mAclContext);

    if (ret != ACL_ERROR_NONE)

    {

        SDKLOG(ERROR) << "acl set context failed! aclError= " << ret;

        return ERROR_INITACL;

    }

    mThresh = thresh;

    mInputHeight = inFrame.cols;

    mInputWidth = inFrame.rows;

    //预处理





    cv::Mat in_mat = inFrame.clone();

    //等比例缩放

    float r = std::min(mModelInputSize.width / static_cast<float>(in_mat.rows), mModelInputSize.height / static_cast<float>(in_mat.cols));

    cv::Size new_size = cv::Size{static_cast<int>(in_mat.cols * r), static_cast<int>(in_mat.rows * r)};

    SDKLOG(INFO) << "model input: "<< mModelInputSize.width  << mModelInputSize.height;

    SDKLOG(INFO) << "cv::Size " << new_size.width << new_size.height  << r;

    SDKLOG(INFO) << "cv::Size inMat " << in_mat.rows << in_mat.cols ;

    cv::Mat resized_mat;

    cv::resize(in_mat, resized_mat, new_size);





    if(m_board.empty())

    {

        m_board = cv::Mat(mModelInputSize, CV_8UC3, cv::Scalar(114, 114, 114));

    }

    resized_mat.copyTo(m_board(cv::Rect{0, 0, resized_mat.cols, resized_mat.rows}));





    //色阈转换BGR2RGB

    cv::cvtColor(m_board, m_board, cv::COLOR_BGR2RGB);

    //转浮点型归一化,hwc2chw

    m_board.convertTo(m_normalized_mat, CV_32FC3, 1/255.);

    // std::vector<cv::Mat> m_chw_wrappers;

    cv::split(m_normalized_mat, m_chw_wrappers);





    if(mAclRunMode == ACL_HOST)

    {

        size_t single_chn_size = m_chw_wrappers[0].rows * m_chw_wrappers[0].cols * sizeof(float);

        aclrtMemcpy(m_input_buffer, single_chn_size, m_chw_wrappers[0].data, single_chn_size, ACL_MEMCPY_HOST_TO_DEVICE);

        aclrtMemcpy((char*)m_input_buffer + single_chn_size, single_chn_size, m_chw_wrappers[1].data, single_chn_size, ACL_MEMCPY_HOST_TO_DEVICE);

        aclrtMemcpy((char*)m_input_buffer + 2 * single_chn_size, single_chn_size, m_chw_wrappers[2].data, single_chn_size, ACL_MEMCPY_HOST_TO_DEVICE);

    }





    SDKLOG(INFO) << "before inference";

    //运行模型推理

    STATUS status = doInference();

    SDKLOG(INFO) << "after inference";





    //解析yolo层的输出

    float scale = std::min(m_input_dims.dims[3] / (in_mat.cols * 1.0), m_input_dims.dims[2] / (in_mat.rows * 1.0));

    std::vector<BoxInfo> detBoxes{};

    void* obuf = nullptr;

    if(mAclRunMode == ACL_HOST)

    {

        size_t cp_size = m_output_dims.dims[0] * m_output_dims.dims[1] * m_output_dims.dims[2] * sizeof(float);

        aclrtMemcpy(m_output_buffer_host, cp_size, m_output_buffer,  cp_size, ACL_MEMCPY_DEVICE_TO_HOST);

        obuf = m_output_buffer_host;

    }

    else

    {

        obuf = m_output_buffer;

    }

    decode_outputs((float*)obuf, detBoxes, scale, in_mat.cols, in_mat.rows);

    runNms(detBoxes);

    result = detBoxes;

    return STATUS_SUCCESS;

}

本帖最后由 匿名用户2023/01/06 14:31:06 编辑

我要发帖子