Serializzare e deserializzare i protobuf tramite la CLI?

Nov 23 2020

Sto cercando di deserializzare un file salvato come protobuf tramite la CLI (sembra la cosa più semplice da fare). Preferirei non usare protoc per compilarlo, importarlo in un linguaggio di programmazione e poi leggere il risultato.

Il mio caso d'uso: uno strumento TensorFlow lite ha generato alcuni dati in un formato protobuf. Ho trovato la messagedefinizione del protobuf anche nel repository TensorFlow. Voglio solo leggere velocemente l'output. Nello specifico, ricevo un tflite::evaluation::EvaluationStageMetricsmessaggio dallo inference_diff strumento .

Risposte

TimoStamm Nov 26 2020 at 23:44

Presumo che lo strumento emetta un messaggio protobuf in formato binario.

protoc può decodificare il messaggio e l'output in formato testo. Vedi questa opzione:

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

Anche se la risposta di Timo Stamms è stata determinante, ho ancora lottato con i percorsi per far funzionare il protocollo in un repo complesso (ad esempio TensorFlow).

Alla fine, questo ha funzionato per me:

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

Qui installo il contenuto binario del file contenente protobuf ( inference_diff.txtnel mio caso, generato seguendo questa guida ), e specifico il messaggio protobuf completo (che ho ottenuto combinando il package tflite.evaluation;e il nome del messaggio EvaluationStageMetrics), il percorso assoluto del progetto per proto_path (che è la radice del progetto / repository TensorFlow), e anche il percorso assoluto per il file che contiene effettivamente il messaggio. proto_pathviene utilizzato solo per risolvere le importazioni, dove come PROTO_FILE (in questo caso, evaluation_config.proto), viene utilizzato per decodificare il file.

Output di esempio

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

Se vuoi solo ottenere i numeri in fretta e non puoi essere disturbato a sistemare i percorsi, puoi farlo

cat inference_diff.txt | protoc --decode_raw

Output di esempio

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