Serializować i deserializować protobufy za pośrednictwem interfejsu wiersza polecenia?

Nov 23 2020

Próbuję deserializować plik zapisany jako protobuf przez CLI (wydaje się to najłatwiejsze do zrobienia). Wolałbym nie używać protokołu do kompilacji, importować go do języka programowania, a następnie odczytywać wynik.

Mój przypadek użycia: narzędzie TensorFlow lite generuje pewne dane w formacie protobuf. Znalazłem messagedefinicję protobuf również w repozytorium TensorFlow. Chcę tylko szybko przeczytać wynik. W szczególności otrzymuję tflite::evaluation::EvaluationStageMetricswiadomość z inference_diff narzędzia .

Odpowiedzi

TimoStamm Nov 26 2020 at 23:44

Zakładam, że narzędzie wysyła wiadomość protobuf w formacie binarnym.

protoc może zdekodować wiadomość i wyprowadzić ją w formacie tekstowym. Zobacz tę opcję:

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

Podczas gdy odpowiedź Timo Stammsa była instrumentalna, wciąż zmagałem się ze ścieżkami, aby Protoc działał w złożonym repozytorium (np. TensorFlow).

W końcu to zadziałało dla mnie:

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

Tutaj potokuję binarną zawartość pliku zawierającego protobuf ( inference_diff.txtw moim przypadku wygenerowaną zgodnie z tym przewodnikiem ) i określam w pełni kwalifikowaną wiadomość protobuf (którą otrzymałem przez połączenie package tflite.evaluation;nazwy wiadomości i EvaluationStageMetrics), bezwzględną ścieżkę projektu dla proto_path (który jest katalogiem głównym projektu / repozytorium TensorFlow), a także bezwzględną ścieżką do pliku, który faktycznie zawiera wiadomość. proto_pathsłuży tylko do rozwiązywania importów, gdzie jako PROTO_FILE (w tym przypadku, evaluation_config.proto) jest używany do dekodowania pliku.

Przykładowe dane wyjściowe

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

Jeśli chcesz po prostu uzyskać liczby w pośpiechu i nie zawracasz sobie głowy naprawianiem ścieżek, możesz to zrobić

cat inference_diff.txt | protoc --decode_raw

Przykładowe dane wyjściowe

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