Serializar e desserializar protobufs por meio da CLI?
Estou tentando desserializar um arquivo salvo como protobuf por meio da CLI (parece a coisa mais fácil de fazer). Eu preferiria não usar o protoc para compilar, importá-lo para uma linguagem de programação e depois ler o resultado.
Meu caso de uso: uma ferramenta TensorFlow Lite gerou alguns dados em formato protobuf. Também encontrei a messagedefinição de protobuf no repositório TensorFlow. Eu só quero ler o resultado rapidamente. Especificamente, estou recebendo uma tflite::evaluation::EvaluationStageMetricsmensagem da inference_diff ferramenta .
Respostas
Presumo que a ferramenta produza uma mensagem protobuf em formato binário.
protoc pode decodificar a mensagem e produzir em formato de texto. Veja esta opção:
--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.
Embora a resposta de Timo Stamms tenha sido instrumental, eu ainda lutava com os caminhos para fazer o protocolo funcionar em um repo complexo (por exemplo, TensorFlow).
No final, isso funcionou para mim:
cat inference_diff.txt | \
protoc --proto_path="/Users/ben/butter/repos/tensorflow/" \
--decode tflite.evaluation.EvaluationStageMetrics \
$(pwd)/evaluation_config.proto
Aqui, canalizo o conteúdo binário do arquivo que contém protobuf ( inference_diff.txtno meu caso, gerado seguindo este guia ) e especifico a mensagem protobuf totalmente qualificada (que obtive combinando o package tflite.evaluation;e o nome da mensagem EvaluationStageMetrics), o caminho absoluto do projeto para o proto_path (que é a raiz do projeto / repositório TensorFlow) e também o caminho absoluto para o arquivo que realmente contém a mensagem. proto_pathé usado apenas para resolver importações, onde como PROTO_FILE (neste caso, evaluation_config.proto), é usado para decodificar o arquivo.
Exemplo de saída
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 você quer apenas obter os números rapidamente e não se dá ao trabalho de consertar os caminhos, pode fazer
cat inference_diff.txt | protoc --decode_raw
Saída de exemplo
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
}
}
}