Serializować i deserializować protobufy za pośrednictwem interfejsu wiersza polecenia?
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 message
definicję protobuf również w repozytorium TensorFlow. Chcę tylko szybko przeczytać wynik. W szczególności otrzymuję tflite::evaluation::EvaluationStageMetrics
wiadomość z inference_diff
narzędzia .
Odpowiedzi
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.
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.txt
w 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_path
sł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
}
}
}