Protobufs über CLI serialisieren und deserialisieren?

Nov 23 2020

Ich versuche, eine als Protobuf über die CLI gespeicherte Datei zu deserialisieren (scheint am einfachsten zu sein). Ich würde es vorziehen, protoc nicht zum Kompilieren zu verwenden, es in eine Programmiersprache zu importieren und dann das Ergebnis zu lesen.

Mein Anwendungsfall: Ein TensorFlow Lite-Tool hat einige Daten in einem Protobuf-Format ausgegeben. Ich habe die Protobuf- messageDefinition auch im TensorFlow-Repo gefunden. Ich möchte nur die Ausgabe schnell lesen. Insbesondere erhalte ich eine tflite::evaluation::EvaluationStageMetricsNachricht vom inference_diff Tool zurück .

Antworten

TimoStamm Nov 26 2020 at 23:44

Ich gehe davon aus, dass das Tool eine Protobuf-Nachricht im Binärformat ausgibt.

protoc kann die Nachricht dekodieren und im Textformat ausgeben. Siehe diese 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

Während Timo Stamms Antwort maßgeblich war, hatte ich immer noch Probleme damit, Protoc in einem komplexen Repo (z. B. TensorFlow) zum Laufen zu bringen.

Am Ende hat das bei mir funktioniert:

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

Hier leite ich den binären Inhalt der Datei mit protobuf ( inference_diff.txtin meinem Fall generiert durch Befolgen dieses Handbuchs ) weiter und gebe die vollständig qualifizierte protobuf-Nachricht (die ich durch Kombinieren des package tflite.evaluation;und des Nachrichtennamens erhalten habe EvaluationStageMetrics) an, den absoluten Pfad des Projekts für den proto_path (das ist das Projekt root / TensorFlow repo) und auch den absoluten Pfad für die Datei, die die Nachricht tatsächlich enthält. proto_pathwird nur zum Auflösen von Importen verwendet, wobei PROTO_FILE (in diesem Fall evaluation_config.proto) zum Dekodieren der Datei verwendet wird.

Beispielausgabe

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
    }
  }
}

Wenn Sie nur die Zahlen in Eile erhalten möchten und sich nicht die Mühe machen müssen, die Pfade zu reparieren, können Sie dies tun

cat inference_diff.txt | protoc --decode_raw

Beispielausgabe

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
    }
  }
}