Sérialiser et désérialiser les protobufs via CLI?

Nov 23 2020

J'essaie de désérialiser un fichier enregistré en tant que protobuf via la CLI (cela semble être la chose la plus simple à faire). Je préférerais ne pas utiliser protoc pour compiler, l'importer dans un langage de programmation et ensuite lire le résultat.

Mon cas d'utilisation: un outil TensorFlow lite a généré des données dans un format protobuf. J'ai également trouvé la messagedéfinition protobuf dans le référentiel TensorFlow. Je veux juste lire la sortie rapidement. Plus précisément, je reçois un tflite::evaluation::EvaluationStageMetricsmessage de l' inference_diff outil .

Réponses

TimoStamm Nov 26 2020 at 23:44

Je suppose que l'outil génère un message protobuf au format binaire.

protoc peut décoder le message et le sortir au format texte. Voir cette option:

  --decode=MESSAGE_TYPE       Read a binary message of the given type from
                              standard input and write it in text format
                              to standard output.  The message type must
                              be defined in PROTO_FILES or their imports.
BenButterworth Nov 28 2020 at 20:16

Bien que la réponse de Timo Stamms ait été déterminante, je me débattais toujours avec les chemins pour faire fonctionner protoc dans un dépôt complexe (par exemple TensorFlow).

En fin de compte, cela a fonctionné pour moi:

cat inference_diff.txt | \
    protoc --proto_path="/Users/ben/butter/repos/tensorflow/" \
    --decode tflite.evaluation.EvaluationStageMetrics \ 
    $(pwd)/evaluation_config.proto

Ici, je pipe le contenu binaire du fichier contenant protobuf ( inference_diff.txtdans mon cas, généré en suivant ce guide ), et spécifie le message protobuf complet (que j'ai obtenu en combinant le package tflite.evaluation;et le nom du message, EvaluationStageMetrics), le chemin absolu du projet pour le proto_path (qui est la racine du projet / le dépôt TensorFlow), ainsi que le chemin absolu du fichier qui contient réellement le message. proto_pathest juste utilisé pour résoudre les importations, où comme PROTO_FILE (dans ce cas, evaluation_config.proto), est utilisé pour décoder le fichier.

Exemple de sortie

num_runs: 50
process_metrics {
  inference_profiler_metrics {
    reference_latency {
      last_us: 455818
      max_us: 577312
      min_us: 453121
      sum_us: 72573828
      avg_us: 483825.52
      std_deviation_us: 37940
    }
    test_latency {
      last_us: 59503
      max_us: 66746
      min_us: 57828
      sum_us: 8992747
      avg_us: 59951.646666666667
      std_deviation_us: 1284
    }
    output_errors {
      max_value: 122.371696
      min_value: 83.0335922
      avg_value: 100.17548828125
      std_deviation: 8.16124535
    }
  }
}

Si vous voulez juste obtenir les chiffres rapidement et que vous ne pouvez pas vous soucier de réparer les chemins, vous pouvez le faire

cat inference_diff.txt | protoc --decode_raw

Exemple de sortie

1: 50
2 {
  5 {
    1 {
      1: 455818
      2: 577312
      3: 453121
      4: 72573828
      5: 0x411d87c6147ae148
      6: 37940
    }
    2 {
      1: 59503
      2: 66746
      3: 57828
      4: 8992747
      5: 0x40ed45f4b17e4b18
      6: 1284
    }
    3 {
      1: 0x42f4be4f
      2: 0x42a61133
      3: 0x40590b3b33333333
      4: 0x41029476
    }
  }
}