Introduction
A GraphDef file holds one TensorFlow
graph: its operations, each a node with a name, an op and inputs, stored as a single
GraphDef Protocol Buffers
message with no header. GraphDef has been TensorFlow’s description of a graph since
the framework was released as open source in November 2015.
The best-known GraphDef files are frozen
graphs, the single-file models of the TensorFlow 1 era: a graph in which every
variable has been replaced by a Const node holding its trained values,
so that one .pb file holds the whole model, weights included. TensorFlow 2
saves whole models as a SavedModel instead, whose
saved_model.pb is a different top-level message and a separate format;
it holds GraphDefs inside it.
GraphDef changes are tracked by version numbers inside the file
(versions); this site treats the files of every version as one format.
A .pb
file dropped on any page of this site opens in the explorer, which shows the GraphDef
version, every node with its op, inputs and device, the ops used and how often, the
functions of the library, and how many Const nodes hold the
weights.
Structure
The file is one GraphDef:
1node one field per node, a NodeDef: name, op, inputs, device and attributes; in a frozen graph the weights are thevalueattributes ofConstnodes, each a TensorProtonearly all of the file2library functions the nodes call, if anyoptional4versions the GraphDef version that wrote it and the oldest that can read ita few bytes
A node of a frozen graph, built for this page: a Const named
w, with attributes dtype = DT_FLOAT and value = a
tensor of shape [2] holding 1.0 and 2.0.
0A 36 0A 01 77 12 05 43 6F 6E 73 74 2A 0B 0A 05 64 74 79 70 65 12 02 30 01 2A 1D …
w, op Const, then the attribute entriesA graph names its inputs by node name, so a program that runs it feeds the
placeholder nodes by name and fetches the outputs it wants, such as
softmax:0.
Telling it apart
The file has no signature. The explorer takes it as Protocol Buffers when the name
ends .pb, .binpb or .onnx, the first field reads
cleanly and the first 512 bytes are not all printable text. After the ONNX and
SavedModel parsers turn it down, the parser for this format checks:
- every top-level field is one of GraphDef’s (1 to 5), with its wire type;
- there is at least one node or a function library;
- every NodeDef checked has a name with no spaces or control characters and an op
made of letters, digits,
_,.,>and-; - the nested messages follow their schemas, down to the first 20,000 fields;
- strings declared
stringare valid UTF-8 (checked up to 4 KB).
The name and op checks matter because a GraphDef’s first field, a list of LEN fields, fits many other messages too. The field numbers are those of TensorFlow’s master branch in November 2026; a later schema that adds a field is still this format, but the parser turns such a file down until it learns the field, and the file is then shown as a message without a schema. No real GraphDef was among the files examined for this site; the parser was tested with files built for the test.
Variants
- ONNX tensor (TensorProto) – one tensor, as in ONNX’s test data
- ONNX sequence or optional value – a list of tensors, or a value that may be absent
- ONNX model (ModelProto) – a whole model: graph, operators and weights
- TensorFlow SavedModel (saved_model.pb) – meta graphs, signatures and functions
- TensorFlow GraphDef (frozen graph) – nodes, with the weights as constants
- Protocol Buffers message – any message, read without its schema
Links
Software
- TensorFlow – the machine learning framework that writes and loads GraphDefs (Windows, macOS, Linux)
- Netron – viewer that draws TensorFlow graphs (Windows, macOS, Linux, web)
Developers
- TensorFlow –
tf.compat.v1.GraphDefto read and write the message, andtf.compat.v1.graph_util.convert_variables_to_constantsto freeze a graph (Python)
Reference
- tensorflow/core/framework – the schemas graph.proto, node_def.proto, attr_value.proto, tensor.proto, types.proto, function.proto and op_def.proto
- Encoding – the Protocol Buffers wire format