Maison >développement back-end >Golang >Comment créer l'API de la bibliothèque d'évaluation Catboost C ?

Comment créer l'API de la bibliothèque d'évaluation Catboost C ?

WBOY
WBOYavant
2024-02-06 08:15:08627parcourir

如何构建Catboost C评估库API?

Contenu de la question

Je dois utiliser le modèle catboost dans certains langages de programmation (golang et python). La meilleure option (pour les performances et la compatibilité) consiste à utiliser une bibliothèque d'évaluation, qui peut être une API C ou C++. J'ai compilé l'API C en suivant la documentation officielle, mais elle présente de nombreux problèmes qui doivent être résolus pour fonctionner.

Voici les problèmes que nous avons rencontrés en essayant de créer une bibliothèque d'évaluation en c :

1.

error: variable has incomplete type 'modelcalcerhandle' (aka 'void')
    modelcalcerhandle modelhandle;
c_wrapper.c:16:13: warning: incompatible pointer types passing 'float (*)[3]' to parameter of type 'const float **' [-wincompatible-pointer-types]
            &floatfeatures, 3,
            ^~~~~~~~~~~~~~
/users/eli/workspace/test_c_api/catboost/catboost/libs/model_interface/c_api.h:151:19: note: passing argument to parameter 'floatfeatures' here
    const float** floatfeatures, size_t floatfeaturessize,
                  ^
c_wrapper.c:17:13: warning: incompatible pointer types passing 'char *(*)[4]' to parameter of type 'const char ***' [-wincompatible-pointer-types]
            &catfeatures, 4,
            ^~~~~~~~~~~~
/users/eli/workspace/test_c_api/catboost/catboost/libs/model_interface/c_api.h:152:19: note: passing argument to parameter 'catfeatures' here
    const char*** catfeatures, size_t catfeaturessize,
                  ^
c_wrapper.c:18:13: warning: incompatible pointer types passing 'double (*)[1]' to parameter of type 'double *' [-wincompatible-pointer-types]
            &result, 1
            ^~~~~~~
/users/eli/workspace/test_c_api/catboost/catboost/libs/model_interface/c_api.h:153:13: note: passing argument to parameter 'result' here
    double* result, size_t resultsize);

Solution :

  1. Nous avons résolu le problème n°1 en redéfinissant la variable modelhandle comme :
modelcalcerhandle *modelhandle = modelcalcercreate();

Après avoir effectué cette modification, le programme c peut être compilé, mais nous obtenons une nouvelle erreur :

[1]    6489 segmentation fault  ./program
  1. L'erreur de segmentation est liée à l'avertissement répertorié à la question n°2. Il faut redéfinir les variables pour y remédier :
float floatfeaturesraw[100];
const float *floatfeatures = floatfeaturesraw;
const char *catfeaturesraw[2] = {"1", "2"};
const char **catfeatures = catfeaturesraw;
double resultraw[1];
double *result = resultraw;

et

if (!CalcModelPredictionSingle(
        modelHandle,
        &floatFeatures, 3,
        &catFeatures, 4,
        result, 1)) //We remove `&`
{
   printf("CalcModelPrediction error message: %s\n", GetErrorString());
}

J'ajouterai la solution complète dans les commentaires, des corrections de code à la façon de compiler le code C.


Bonne réponse


Voici la solution complète :

  1. Cloner le référentiel catboost :

git 克隆 https://github.com/catboost/catboost.git

  1. Ouvrez le répertoire catboost à partir de votre copie locale du référentiel catboost.

  2. Construisez la bibliothèque d'évaluation (j'ai choisi la bibliothèque partagée, mais vous pouvez choisir de quelle bibliothèque vous avez besoin). Dans mon cas j'ai dû changer le paramètre --target-platform, j'utilise mac m1 et macos ventura 13.1, la version clang est 14.0.0 :

./ya make -r catboost/libs/model_interface --target-platform clang14-darwin-arm64
  1. Créez un fichier c. Exemple de code C fixe :
#include <stdio.h>
#include <c_api.h>

int main()
{
    float floatfeaturesraw[3] = {0, 89, 1};
    const float *floatfeatures = floatfeaturesraw;
    const char *catfeaturesraw[4] = {"others", "443_https", "6", "24"};
    const char **catfeatures = catfeaturesraw;
    double resultraw[4];
    double *result = resultraw;

    modelcalcerhandle *modelhandle = modelcalcercreate();
    if (!loadfullmodelfromfile(modelhandle, "catboost_model"))
    {
        printf("loadfullmodelfromfile error message: %s\n", geterrorstring());
    }
    setpredictiontype(modelhandle, 3);
    if (!calcmodelpredictionsingle(
            modelhandle,
            floatfeatures, 3,
            catfeatures, 4,
            result, 4))
    {
        printf("calcmodelprediction error message: %s\n", geterrorstring());
    }
    printf("%f\n", result[0]);
    printf("%f\n", result[1]);
    printf("%f\n", result[2]);
    printf("%f\n", result[3]);
    modelcalcerdelete(modelhandle);
}

Considérez :

  • J'ai réglé setpredictiontype sur apt_probability
  • Notre modèle prédit plusieurs classes, donc result[4].
  • Nous n'avons besoin de prédire qu'un seul enregistrement à la fois, nous utilisons donc la méthode calcmodelpredictionsingle.
  1. Compilez le code c :
gcc -v -o program.out c_code.c -l catboostmodel -i /path/to/catboost/repo/catboost/catboost/libs/model_interface/ -l /path/to/catboost/repo/catboost/catboost/libs/model_interface/

Important : Assurez-vous qu'aucun message d'avertissement ou d'erreur ne s'affiche.

  1. Vous pouvez maintenant l'exécuter :

Important : Assurez-vous que le fichier du modèle catboost se trouve dans le même chemin que program.out.

./program.out

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer