{
  "format": "tensorviz.graph",
  "version": 3,
  "exportedAt": "2026-09-17T06:47:49.423016+00:00",
  "status": "static",
  "warningCount": 0,
  "document": {
    "schemaVersion": 2,
    "semantic": {
      "graph_id": "snapshot",
      "name": "TinyCLIP",
      "revision": 0,
      "nodes": [
        {
          "node_id": "input",
          "kind": "input",
          "op": "Input",
          "params": {
            "shape": "3,3,8,8"
          },
          "in_ports": [],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "input",
              "name": "Input",
              "displayName": "Input",
              "description": "Model input node",
              "icon": "ArrowRight",
              "category": "io",
              "parameters": [
                {
                  "name": "shape",
                  "type": "string",
                  "defaultValue": "1,3,224,224",
                  "required": true,
                  "description": "Input tensor shape (comma-separated, e.g., 1,3,224,224)"
                },
                {
                  "name": "name",
                  "type": "string",
                  "defaultValue": "input",
                  "required": false,
                  "description": "Name for this input"
                }
              ]
            }
          }
        },
        {
          "node_id": "image_encoder",
          "kind": "module",
          "op": "Module",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "module",
              "name": "Module",
              "displayName": "Module",
              "description": "Custom module group (nn.Module)",
              "icon": "Package",
              "category": "module",
              "parameters": [
                {
                  "name": "name",
                  "type": "string",
                  "defaultValue": "CustomModule",
                  "required": true,
                  "description": "Module class name"
                },
                {
                  "name": "description",
                  "type": "string",
                  "defaultValue": "",
                  "required": false,
                  "description": "Module description"
                }
              ]
            },
            "moduleInstanceId": "image_encoder",
            "moduleTemplateId": "model::ImageEncoder",
            "isGroup": true,
            "moduleMembers": [
              "image_encoder.patches",
              "flatten@image_encoder#0",
              "python@image_encoder#0",
              "image_encoder.class_token",
              "cat@image_encoder#0",
              "image_encoder.positions",
              "add@image_encoder#0",
              "image_encoder.pre_norm",
              "image_encoder.block",
              "image_encoder.post_norm",
              "image_encoder.project",
              "python@image_encoder#1"
            ],
            "moduleLayerCount": 29
          }
        },
        {
          "node_id": "text_encoder",
          "kind": "module",
          "op": "Module",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "module",
              "name": "Module",
              "displayName": "Module",
              "description": "Custom module group (nn.Module)",
              "icon": "Package",
              "category": "module",
              "parameters": [
                {
                  "name": "name",
                  "type": "string",
                  "defaultValue": "CustomModule",
                  "required": true,
                  "description": "Module class name"
                },
                {
                  "name": "description",
                  "type": "string",
                  "defaultValue": "",
                  "required": false,
                  "description": "Module description"
                }
              ]
            },
            "moduleInstanceId": "text_encoder",
            "moduleTemplateId": "model::TextEncoder",
            "isGroup": true,
            "moduleMembers": [
              "text_encoder.tokens",
              "text_encoder.positions",
              "add@text_encoder#0",
              "text_encoder.block",
              "text_encoder.norm",
              "text_encoder.project",
              "python@text_encoder#0"
            ],
            "moduleLayerCount": 24
          }
        },
        {
          "node_id": "similarity",
          "kind": "module",
          "op": "Module",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "module",
              "name": "Module",
              "displayName": "Module",
              "description": "Custom module group (nn.Module)",
              "icon": "Package",
              "category": "module",
              "parameters": [
                {
                  "name": "name",
                  "type": "string",
                  "defaultValue": "CustomModule",
                  "required": true,
                  "description": "Module class name"
                },
                {
                  "name": "description",
                  "type": "string",
                  "defaultValue": "",
                  "required": false,
                  "description": "Module description"
                }
              ]
            },
            "moduleInstanceId": "similarity",
            "moduleTemplateId": "model::PairSimilarity",
            "isGroup": true,
            "moduleMembers": [
              "similarity.log_scale",
              "mul@similarity#0"
            ],
            "moduleLayerCount": 2
          }
        },
        {
          "node_id": "output",
          "kind": "output",
          "op": "Output",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [],
          "metadata": {
            "layerType": {
              "id": "output",
              "name": "Output",
              "displayName": "Output",
              "description": "Model output node",
              "icon": "ArrowLeft",
              "category": "io",
              "parameters": [
                {
                  "name": "name",
                  "type": "string",
                  "defaultValue": "output",
                  "required": false,
                  "description": "Name for this output"
                }
              ]
            }
          }
        },
        {
          "node_id": "image_encoder.patches",
          "kind": "layer",
          "op": "Conv2d",
          "params": {
            "in_channels": 3,
            "out_channels": 8,
            "kernel_size": 4,
            "stride": 4,
            "bias": false
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "conv2d",
              "name": "Conv2d",
              "displayName": "Conv2D",
              "description": "2D Convolutional Layer",
              "icon": "Grid3X3",
              "category": "conv",
              "parameters": [
                {
                  "name": "in_channels",
                  "type": "number",
                  "defaultValue": 3,
                  "required": true,
                  "description": "Number of input channels",
                  "min": 1
                },
                {
                  "name": "out_channels",
                  "type": "number",
                  "defaultValue": 64,
                  "required": true,
                  "description": "Number of output channels",
                  "min": 1
                },
                {
                  "name": "kernel_size",
                  "type": "number",
                  "defaultValue": 3,
                  "required": true,
                  "description": "Size of the convolving kernel",
                  "min": 1
                },
                {
                  "name": "stride",
                  "type": "number",
                  "defaultValue": 1,
                  "required": false,
                  "description": "Stride of the convolution",
                  "min": 1
                },
                {
                  "name": "padding",
                  "type": "number",
                  "defaultValue": 0,
                  "required": false,
                  "description": "Zero-padding added to both sides",
                  "min": 0
                },
                {
                  "name": "dilation",
                  "type": "number",
                  "defaultValue": 1,
                  "required": false,
                  "description": "Spacing between kernel elements",
                  "min": 1
                },
                {
                  "name": "groups",
                  "type": "number",
                  "defaultValue": 1,
                  "required": false,
                  "description": "Number of blocked connections from input to output channels",
                  "min": 1
                },
                {
                  "name": "bias",
                  "type": "boolean",
                  "defaultValue": true,
                  "required": false,
                  "description": "If True, adds a learnable bias"
                }
              ]
            },
            "parentId": "image_encoder"
          }
        },
        {
          "node_id": "flatten@image_encoder#0",
          "kind": "layer",
          "op": "Flatten",
          "params": {
            "start_dim": 2
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "flatten",
              "name": "Flatten",
              "displayName": "Flatten",
              "description": "Flattens input tensor contiguously",
              "icon": "Maximize2",
              "category": "tensor",
              "parameters": [
                {
                  "name": "start_dim",
                  "type": "number",
                  "defaultValue": 1,
                  "required": false,
                  "description": "First dim to flatten",
                  "min": 0
                },
                {
                  "name": "end_dim",
                  "type": "number",
                  "defaultValue": -1,
                  "required": false,
                  "description": "Last dim to flatten"
                }
              ]
            },
            "parentId": "image_encoder"
          }
        },
        {
          "node_id": "python@image_encoder#0",
          "kind": "layer",
          "op": "Python",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "python",
              "name": "Python",
              "displayName": "Python",
              "description": "A statement from the source file that has no graph equivalent. Its code is kept verbatim and its shape is unknown until the model is traced.",
              "icon": "Hash",
              "category": "misc",
              "parameters": []
            },
            "parentId": "image_encoder"
          }
        },
        {
          "node_id": "image_encoder.class_token",
          "kind": "layer",
          "op": "Parameter",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "parameter",
              "description": "",
              "category": "misc",
              "icon": "Box",
              "parameters": [],
              "name": "Parameter",
              "displayName": "Parameter"
            },
            "parentId": "image_encoder"
          }
        },
        {
          "node_id": "cat@image_encoder#0",
          "kind": "layer",
          "op": "torch.cat",
          "params": {
            "dim": 1
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "cat",
              "name": "torch.cat",
              "displayName": "torch.cat",
              "description": "PyTorch cat operation",
              "icon": "Activity",
              "category": "tensor",
              "parameters": [
                {
                  "name": "dim",
                  "type": "string",
                  "defaultValue": "",
                  "required": false,
                  "description": "Dimension(s) to apply the operation on"
                }
              ]
            },
            "parentId": "image_encoder"
          }
        },
        {
          "node_id": "image_encoder.positions",
          "kind": "layer",
          "op": "Parameter",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "parameter",
              "description": "",
              "category": "misc",
              "icon": "Box",
              "parameters": [],
              "name": "Parameter",
              "displayName": "Parameter"
            },
            "parentId": "image_encoder"
          }
        },
        {
          "node_id": "add@image_encoder#0",
          "kind": "layer",
          "op": "torch.add",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "add",
              "name": "torch.add",
              "displayName": "torch.add",
              "description": "PyTorch add operation",
              "icon": "Activity",
              "category": "tensor",
              "parameters": [
                {
                  "name": "dim",
                  "type": "string",
                  "defaultValue": "",
                  "required": false,
                  "description": "Dimension(s) to apply the operation on"
                }
              ]
            },
            "parentId": "image_encoder"
          }
        },
        {
          "node_id": "image_encoder.pre_norm",
          "kind": "layer",
          "op": "LayerNorm",
          "params": {
            "normalized_shape": 8
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "layernorm",
              "name": "LayerNorm",
              "displayName": "LayerNorm",
              "description": "Layer Normalization",
              "icon": "Layers",
              "category": "norm",
              "parameters": [
                {
                  "name": "normalized_shape",
                  "type": "string",
                  "defaultValue": "512",
                  "required": true,
                  "description": "Input shape for normalization (comma-separated for multi-dim, e.g., 512)"
                },
                {
                  "name": "eps",
                  "type": "number",
                  "defaultValue": 0.00001,
                  "required": false,
                  "description": "Value for numerical stability",
                  "min": 0
                },
                {
                  "name": "elementwise_affine",
                  "type": "boolean",
                  "defaultValue": true,
                  "required": false,
                  "description": "If True, learnable affine parameters"
                }
              ]
            },
            "parentId": "image_encoder"
          }
        },
        {
          "node_id": "image_encoder.block",
          "kind": "module",
          "op": "Module",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "module",
              "name": "Module",
              "displayName": "Module",
              "description": "Custom module group (nn.Module)",
              "icon": "Package",
              "category": "module",
              "parameters": [
                {
                  "name": "name",
                  "type": "string",
                  "defaultValue": "CustomModule",
                  "required": true,
                  "description": "Module class name"
                },
                {
                  "name": "description",
                  "type": "string",
                  "defaultValue": "",
                  "required": false,
                  "description": "Module description"
                }
              ]
            },
            "parentId": "image_encoder",
            "moduleInstanceId": "image_encoder.block",
            "moduleTemplateId": "model::EncoderBlock",
            "isGroup": true,
            "moduleMembers": [
              "image_encoder.block.norm",
              "image_encoder.block.query",
              "python@image_encoder.block#0",
              "image_encoder.block.key",
              "python@image_encoder.block#1",
              "div@image_encoder.block#0",
              "python@image_encoder.block#3",
              "image_encoder.block.value",
              "python@image_encoder.block#2",
              "image_encoder.block.softmax",
              "python@image_encoder.block#4",
              "image_encoder.block.project",
              "add@image_encoder.block#0",
              "image_encoder.block.ff_norm",
              "image_encoder.block.up",
              "image_encoder.block.gelu",
              "image_encoder.block.down",
              "add@image_encoder.block#1"
            ],
            "moduleLayerCount": 18
          }
        },
        {
          "node_id": "image_encoder.post_norm",
          "kind": "layer",
          "op": "LayerNorm",
          "params": {
            "normalized_shape": 8
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "layernorm",
              "name": "LayerNorm",
              "displayName": "LayerNorm",
              "description": "Layer Normalization",
              "icon": "Layers",
              "category": "norm",
              "parameters": [
                {
                  "name": "normalized_shape",
                  "type": "string",
                  "defaultValue": "512",
                  "required": true,
                  "description": "Input shape for normalization (comma-separated for multi-dim, e.g., 512)"
                },
                {
                  "name": "eps",
                  "type": "number",
                  "defaultValue": 0.00001,
                  "required": false,
                  "description": "Value for numerical stability",
                  "min": 0
                },
                {
                  "name": "elementwise_affine",
                  "type": "boolean",
                  "defaultValue": true,
                  "required": false,
                  "description": "If True, learnable affine parameters"
                }
              ]
            },
            "parentId": "image_encoder"
          }
        },
        {
          "node_id": "image_encoder.project",
          "kind": "layer",
          "op": "Linear",
          "params": {
            "in_features": 8,
            "out_features": 4,
            "bias": false
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "linear",
              "name": "Linear",
              "displayName": "Linear",
              "description": "Fully Connected Layer",
              "icon": "Minus",
              "category": "linear",
              "parameters": [
                {
                  "name": "in_features",
                  "type": "number",
                  "defaultValue": 512,
                  "required": true,
                  "description": "Size of input features",
                  "min": 1
                },
                {
                  "name": "out_features",
                  "type": "number",
                  "defaultValue": 256,
                  "required": true,
                  "description": "Size of output features",
                  "min": 1
                },
                {
                  "name": "bias",
                  "type": "boolean",
                  "defaultValue": true,
                  "required": false,
                  "description": "If set to False, the layer will not learn an additive bias"
                }
              ]
            },
            "parentId": "image_encoder"
          }
        },
        {
          "node_id": "python@image_encoder#1",
          "kind": "layer",
          "op": "Python",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "python",
              "name": "Python",
              "displayName": "Python",
              "description": "A statement from the source file that has no graph equivalent. Its code is kept verbatim and its shape is unknown until the model is traced.",
              "icon": "Hash",
              "category": "misc",
              "parameters": []
            },
            "parentId": "image_encoder"
          }
        },
        {
          "node_id": "image_encoder.block.norm",
          "kind": "layer",
          "op": "LayerNorm",
          "params": {
            "normalized_shape": 8
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "layernorm",
              "name": "LayerNorm",
              "displayName": "LayerNorm",
              "description": "Layer Normalization",
              "icon": "Layers",
              "category": "norm",
              "parameters": [
                {
                  "name": "normalized_shape",
                  "type": "string",
                  "defaultValue": "512",
                  "required": true,
                  "description": "Input shape for normalization (comma-separated for multi-dim, e.g., 512)"
                },
                {
                  "name": "eps",
                  "type": "number",
                  "defaultValue": 0.00001,
                  "required": false,
                  "description": "Value for numerical stability",
                  "min": 0
                },
                {
                  "name": "elementwise_affine",
                  "type": "boolean",
                  "defaultValue": true,
                  "required": false,
                  "description": "If True, learnable affine parameters"
                }
              ]
            },
            "parentId": "image_encoder.block"
          }
        },
        {
          "node_id": "image_encoder.block.query",
          "kind": "layer",
          "op": "Linear",
          "params": {
            "in_features": 8,
            "out_features": 8
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "linear",
              "name": "Linear",
              "displayName": "Linear",
              "description": "Fully Connected Layer",
              "icon": "Minus",
              "category": "linear",
              "parameters": [
                {
                  "name": "in_features",
                  "type": "number",
                  "defaultValue": 512,
                  "required": true,
                  "description": "Size of input features",
                  "min": 1
                },
                {
                  "name": "out_features",
                  "type": "number",
                  "defaultValue": 256,
                  "required": true,
                  "description": "Size of output features",
                  "min": 1
                },
                {
                  "name": "bias",
                  "type": "boolean",
                  "defaultValue": true,
                  "required": false,
                  "description": "If set to False, the layer will not learn an additive bias"
                }
              ]
            },
            "parentId": "image_encoder.block"
          }
        },
        {
          "node_id": "python@image_encoder.block#0",
          "kind": "layer",
          "op": "Python",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "python",
              "name": "Python",
              "displayName": "Python",
              "description": "A statement from the source file that has no graph equivalent. Its code is kept verbatim and its shape is unknown until the model is traced.",
              "icon": "Hash",
              "category": "misc",
              "parameters": []
            },
            "parentId": "image_encoder.block"
          }
        },
        {
          "node_id": "image_encoder.block.key",
          "kind": "layer",
          "op": "Linear",
          "params": {
            "in_features": 8,
            "out_features": 8
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "linear",
              "name": "Linear",
              "displayName": "Linear",
              "description": "Fully Connected Layer",
              "icon": "Minus",
              "category": "linear",
              "parameters": [
                {
                  "name": "in_features",
                  "type": "number",
                  "defaultValue": 512,
                  "required": true,
                  "description": "Size of input features",
                  "min": 1
                },
                {
                  "name": "out_features",
                  "type": "number",
                  "defaultValue": 256,
                  "required": true,
                  "description": "Size of output features",
                  "min": 1
                },
                {
                  "name": "bias",
                  "type": "boolean",
                  "defaultValue": true,
                  "required": false,
                  "description": "If set to False, the layer will not learn an additive bias"
                }
              ]
            },
            "parentId": "image_encoder.block"
          }
        },
        {
          "node_id": "python@image_encoder.block#1",
          "kind": "layer",
          "op": "Python",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "python",
              "name": "Python",
              "displayName": "Python",
              "description": "A statement from the source file that has no graph equivalent. Its code is kept verbatim and its shape is unknown until the model is traced.",
              "icon": "Hash",
              "category": "misc",
              "parameters": []
            },
            "parentId": "image_encoder.block"
          }
        },
        {
          "node_id": "div@image_encoder.block#0",
          "kind": "layer",
          "op": "torch.div",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "div",
              "name": "torch.div",
              "displayName": "torch.div",
              "description": "PyTorch div operation",
              "icon": "Activity",
              "category": "tensor",
              "parameters": [
                {
                  "name": "dim",
                  "type": "string",
                  "defaultValue": "",
                  "required": false,
                  "description": "Dimension(s) to apply the operation on"
                }
              ]
            },
            "parentId": "image_encoder.block"
          }
        },
        {
          "node_id": "python@image_encoder.block#3",
          "kind": "layer",
          "op": "Python",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "python",
              "name": "Python",
              "displayName": "Python",
              "description": "A statement from the source file that has no graph equivalent. Its code is kept verbatim and its shape is unknown until the model is traced.",
              "icon": "Hash",
              "category": "misc",
              "parameters": []
            },
            "parentId": "image_encoder.block"
          }
        },
        {
          "node_id": "image_encoder.block.value",
          "kind": "layer",
          "op": "Linear",
          "params": {
            "in_features": 8,
            "out_features": 8
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "linear",
              "name": "Linear",
              "displayName": "Linear",
              "description": "Fully Connected Layer",
              "icon": "Minus",
              "category": "linear",
              "parameters": [
                {
                  "name": "in_features",
                  "type": "number",
                  "defaultValue": 512,
                  "required": true,
                  "description": "Size of input features",
                  "min": 1
                },
                {
                  "name": "out_features",
                  "type": "number",
                  "defaultValue": 256,
                  "required": true,
                  "description": "Size of output features",
                  "min": 1
                },
                {
                  "name": "bias",
                  "type": "boolean",
                  "defaultValue": true,
                  "required": false,
                  "description": "If set to False, the layer will not learn an additive bias"
                }
              ]
            },
            "parentId": "image_encoder.block"
          }
        },
        {
          "node_id": "python@image_encoder.block#2",
          "kind": "layer",
          "op": "Python",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "python",
              "name": "Python",
              "displayName": "Python",
              "description": "A statement from the source file that has no graph equivalent. Its code is kept verbatim and its shape is unknown until the model is traced.",
              "icon": "Hash",
              "category": "misc",
              "parameters": []
            },
            "parentId": "image_encoder.block"
          }
        },
        {
          "node_id": "image_encoder.block.softmax",
          "kind": "layer",
          "op": "Softmax",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "softmax",
              "name": "Softmax",
              "displayName": "Softmax",
              "description": "Softmax over a dimension",
              "icon": "TrendingUp",
              "category": "activation",
              "parameters": [
                {
                  "name": "dim",
                  "type": "number",
                  "defaultValue": 1,
                  "required": true,
                  "description": "Dimension along which Softmax is computed"
                }
              ]
            },
            "parentId": "image_encoder.block"
          }
        },
        {
          "node_id": "python@image_encoder.block#4",
          "kind": "layer",
          "op": "Python",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "python",
              "name": "Python",
              "displayName": "Python",
              "description": "A statement from the source file that has no graph equivalent. Its code is kept verbatim and its shape is unknown until the model is traced.",
              "icon": "Hash",
              "category": "misc",
              "parameters": []
            },
            "parentId": "image_encoder.block"
          }
        },
        {
          "node_id": "image_encoder.block.project",
          "kind": "layer",
          "op": "Linear",
          "params": {
            "in_features": 8,
            "out_features": 8
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "linear",
              "name": "Linear",
              "displayName": "Linear",
              "description": "Fully Connected Layer",
              "icon": "Minus",
              "category": "linear",
              "parameters": [
                {
                  "name": "in_features",
                  "type": "number",
                  "defaultValue": 512,
                  "required": true,
                  "description": "Size of input features",
                  "min": 1
                },
                {
                  "name": "out_features",
                  "type": "number",
                  "defaultValue": 256,
                  "required": true,
                  "description": "Size of output features",
                  "min": 1
                },
                {
                  "name": "bias",
                  "type": "boolean",
                  "defaultValue": true,
                  "required": false,
                  "description": "If set to False, the layer will not learn an additive bias"
                }
              ]
            },
            "parentId": "image_encoder.block"
          }
        },
        {
          "node_id": "add@image_encoder.block#0",
          "kind": "layer",
          "op": "torch.add",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "add",
              "name": "torch.add",
              "displayName": "torch.add",
              "description": "PyTorch add operation",
              "icon": "Activity",
              "category": "tensor",
              "parameters": [
                {
                  "name": "dim",
                  "type": "string",
                  "defaultValue": "",
                  "required": false,
                  "description": "Dimension(s) to apply the operation on"
                }
              ]
            },
            "parentId": "image_encoder.block"
          }
        },
        {
          "node_id": "image_encoder.block.ff_norm",
          "kind": "layer",
          "op": "LayerNorm",
          "params": {
            "normalized_shape": 8
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "layernorm",
              "name": "LayerNorm",
              "displayName": "LayerNorm",
              "description": "Layer Normalization",
              "icon": "Layers",
              "category": "norm",
              "parameters": [
                {
                  "name": "normalized_shape",
                  "type": "string",
                  "defaultValue": "512",
                  "required": true,
                  "description": "Input shape for normalization (comma-separated for multi-dim, e.g., 512)"
                },
                {
                  "name": "eps",
                  "type": "number",
                  "defaultValue": 0.00001,
                  "required": false,
                  "description": "Value for numerical stability",
                  "min": 0
                },
                {
                  "name": "elementwise_affine",
                  "type": "boolean",
                  "defaultValue": true,
                  "required": false,
                  "description": "If True, learnable affine parameters"
                }
              ]
            },
            "parentId": "image_encoder.block"
          }
        },
        {
          "node_id": "image_encoder.block.up",
          "kind": "layer",
          "op": "Linear",
          "params": {
            "in_features": 8,
            "out_features": 32
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "linear",
              "name": "Linear",
              "displayName": "Linear",
              "description": "Fully Connected Layer",
              "icon": "Minus",
              "category": "linear",
              "parameters": [
                {
                  "name": "in_features",
                  "type": "number",
                  "defaultValue": 512,
                  "required": true,
                  "description": "Size of input features",
                  "min": 1
                },
                {
                  "name": "out_features",
                  "type": "number",
                  "defaultValue": 256,
                  "required": true,
                  "description": "Size of output features",
                  "min": 1
                },
                {
                  "name": "bias",
                  "type": "boolean",
                  "defaultValue": true,
                  "required": false,
                  "description": "If set to False, the layer will not learn an additive bias"
                }
              ]
            },
            "parentId": "image_encoder.block"
          }
        },
        {
          "node_id": "image_encoder.block.gelu",
          "kind": "layer",
          "op": "GELU",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "gelu",
              "name": "GELU",
              "displayName": "GELU",
              "description": "Gaussian Error Linear Unit",
              "icon": "TrendingUp",
              "category": "activation",
              "parameters": [
                {
                  "name": "approximate",
                  "type": "select",
                  "defaultValue": "none",
                  "required": false,
                  "description": "The gelu approximation algorithm to use: 'none' or 'tanh'",
                  "options": [
                    "none",
                    "tanh"
                  ]
                }
              ]
            },
            "parentId": "image_encoder.block"
          }
        },
        {
          "node_id": "image_encoder.block.down",
          "kind": "layer",
          "op": "Linear",
          "params": {
            "in_features": 32,
            "out_features": 8
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "linear",
              "name": "Linear",
              "displayName": "Linear",
              "description": "Fully Connected Layer",
              "icon": "Minus",
              "category": "linear",
              "parameters": [
                {
                  "name": "in_features",
                  "type": "number",
                  "defaultValue": 512,
                  "required": true,
                  "description": "Size of input features",
                  "min": 1
                },
                {
                  "name": "out_features",
                  "type": "number",
                  "defaultValue": 256,
                  "required": true,
                  "description": "Size of output features",
                  "min": 1
                },
                {
                  "name": "bias",
                  "type": "boolean",
                  "defaultValue": true,
                  "required": false,
                  "description": "If set to False, the layer will not learn an additive bias"
                }
              ]
            },
            "parentId": "image_encoder.block"
          }
        },
        {
          "node_id": "add@image_encoder.block#1",
          "kind": "layer",
          "op": "torch.add",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "add",
              "name": "torch.add",
              "displayName": "torch.add",
              "description": "PyTorch add operation",
              "icon": "Activity",
              "category": "tensor",
              "parameters": [
                {
                  "name": "dim",
                  "type": "string",
                  "defaultValue": "",
                  "required": false,
                  "description": "Dimension(s) to apply the operation on"
                }
              ]
            },
            "parentId": "image_encoder.block"
          }
        },
        {
          "node_id": "text_encoder.tokens",
          "kind": "layer",
          "op": "Embedding",
          "params": {
            "num_embeddings": 16,
            "embedding_dim": 8
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "embedding",
              "name": "Embedding",
              "displayName": "Embedding",
              "description": "Lookup table for dense vector embeddings",
              "icon": "Hash",
              "category": "embedding",
              "parameters": [
                {
                  "name": "num_embeddings",
                  "type": "number",
                  "defaultValue": 10000,
                  "required": true,
                  "description": "Size of the dictionary of embeddings",
                  "min": 1
                },
                {
                  "name": "embedding_dim",
                  "type": "number",
                  "defaultValue": 128,
                  "required": true,
                  "description": "Size of each embedding vector",
                  "min": 1
                },
                {
                  "name": "padding_idx",
                  "type": "number",
                  "defaultValue": 0,
                  "required": false,
                  "description": "Pad output with zeros at this index",
                  "min": 0
                },
                {
                  "name": "max_norm",
                  "type": "number",
                  "defaultValue": 0,
                  "required": false,
                  "description": "If > 0, re-normalizes embeddings with norm > max_norm",
                  "min": 0
                },
                {
                  "name": "sparse",
                  "type": "boolean",
                  "defaultValue": false,
                  "required": false,
                  "description": "If True, gradient w.r.t. weight is sparse"
                }
              ]
            },
            "parentId": "text_encoder"
          }
        },
        {
          "node_id": "text_encoder.positions",
          "kind": "layer",
          "op": "Parameter",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "parameter",
              "description": "",
              "category": "misc",
              "icon": "Box",
              "parameters": [],
              "name": "Parameter",
              "displayName": "Parameter"
            },
            "parentId": "text_encoder"
          }
        },
        {
          "node_id": "add@text_encoder#0",
          "kind": "layer",
          "op": "torch.add",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "add",
              "name": "torch.add",
              "displayName": "torch.add",
              "description": "PyTorch add operation",
              "icon": "Activity",
              "category": "tensor",
              "parameters": [
                {
                  "name": "dim",
                  "type": "string",
                  "defaultValue": "",
                  "required": false,
                  "description": "Dimension(s) to apply the operation on"
                }
              ]
            },
            "parentId": "text_encoder"
          }
        },
        {
          "node_id": "text_encoder.block",
          "kind": "module",
          "op": "Module",
          "params": {
            "causal": true
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "module",
              "name": "Module",
              "displayName": "Module",
              "description": "Custom module group (nn.Module)",
              "icon": "Package",
              "category": "module",
              "parameters": [
                {
                  "name": "name",
                  "type": "string",
                  "defaultValue": "CustomModule",
                  "required": true,
                  "description": "Module class name"
                },
                {
                  "name": "description",
                  "type": "string",
                  "defaultValue": "",
                  "required": false,
                  "description": "Module description"
                }
              ]
            },
            "parentId": "text_encoder",
            "moduleInstanceId": "text_encoder.block",
            "moduleTemplateId": "model::EncoderBlock",
            "isGroup": true,
            "moduleMembers": [
              "text_encoder.block.norm",
              "text_encoder.block.query",
              "python@text_encoder.block#0",
              "text_encoder.block.key",
              "python@text_encoder.block#1",
              "div@text_encoder.block#0",
              "python@text_encoder.block#3",
              "text_encoder.block.value",
              "python@text_encoder.block#2",
              "text_encoder.block.softmax",
              "python@text_encoder.block#4",
              "text_encoder.block.project",
              "add@text_encoder.block#0",
              "text_encoder.block.ff_norm",
              "text_encoder.block.up",
              "text_encoder.block.gelu",
              "text_encoder.block.down",
              "add@text_encoder.block#1"
            ],
            "moduleLayerCount": 18
          }
        },
        {
          "node_id": "text_encoder.norm",
          "kind": "layer",
          "op": "LayerNorm",
          "params": {
            "normalized_shape": 8
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "layernorm",
              "name": "LayerNorm",
              "displayName": "LayerNorm",
              "description": "Layer Normalization",
              "icon": "Layers",
              "category": "norm",
              "parameters": [
                {
                  "name": "normalized_shape",
                  "type": "string",
                  "defaultValue": "512",
                  "required": true,
                  "description": "Input shape for normalization (comma-separated for multi-dim, e.g., 512)"
                },
                {
                  "name": "eps",
                  "type": "number",
                  "defaultValue": 0.00001,
                  "required": false,
                  "description": "Value for numerical stability",
                  "min": 0
                },
                {
                  "name": "elementwise_affine",
                  "type": "boolean",
                  "defaultValue": true,
                  "required": false,
                  "description": "If True, learnable affine parameters"
                }
              ]
            },
            "parentId": "text_encoder"
          }
        },
        {
          "node_id": "text_encoder.project",
          "kind": "layer",
          "op": "Linear",
          "params": {
            "in_features": 8,
            "out_features": 4,
            "bias": false
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "linear",
              "name": "Linear",
              "displayName": "Linear",
              "description": "Fully Connected Layer",
              "icon": "Minus",
              "category": "linear",
              "parameters": [
                {
                  "name": "in_features",
                  "type": "number",
                  "defaultValue": 512,
                  "required": true,
                  "description": "Size of input features",
                  "min": 1
                },
                {
                  "name": "out_features",
                  "type": "number",
                  "defaultValue": 256,
                  "required": true,
                  "description": "Size of output features",
                  "min": 1
                },
                {
                  "name": "bias",
                  "type": "boolean",
                  "defaultValue": true,
                  "required": false,
                  "description": "If set to False, the layer will not learn an additive bias"
                }
              ]
            },
            "parentId": "text_encoder"
          }
        },
        {
          "node_id": "python@text_encoder#0",
          "kind": "layer",
          "op": "Python",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "python",
              "name": "Python",
              "displayName": "Python",
              "description": "A statement from the source file that has no graph equivalent. Its code is kept verbatim and its shape is unknown until the model is traced.",
              "icon": "Hash",
              "category": "misc",
              "parameters": []
            },
            "parentId": "text_encoder"
          }
        },
        {
          "node_id": "text_encoder.block.norm",
          "kind": "layer",
          "op": "LayerNorm",
          "params": {
            "normalized_shape": 8
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "layernorm",
              "name": "LayerNorm",
              "displayName": "LayerNorm",
              "description": "Layer Normalization",
              "icon": "Layers",
              "category": "norm",
              "parameters": [
                {
                  "name": "normalized_shape",
                  "type": "string",
                  "defaultValue": "512",
                  "required": true,
                  "description": "Input shape for normalization (comma-separated for multi-dim, e.g., 512)"
                },
                {
                  "name": "eps",
                  "type": "number",
                  "defaultValue": 0.00001,
                  "required": false,
                  "description": "Value for numerical stability",
                  "min": 0
                },
                {
                  "name": "elementwise_affine",
                  "type": "boolean",
                  "defaultValue": true,
                  "required": false,
                  "description": "If True, learnable affine parameters"
                }
              ]
            },
            "parentId": "text_encoder.block"
          }
        },
        {
          "node_id": "text_encoder.block.query",
          "kind": "layer",
          "op": "Linear",
          "params": {
            "in_features": 8,
            "out_features": 8
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "linear",
              "name": "Linear",
              "displayName": "Linear",
              "description": "Fully Connected Layer",
              "icon": "Minus",
              "category": "linear",
              "parameters": [
                {
                  "name": "in_features",
                  "type": "number",
                  "defaultValue": 512,
                  "required": true,
                  "description": "Size of input features",
                  "min": 1
                },
                {
                  "name": "out_features",
                  "type": "number",
                  "defaultValue": 256,
                  "required": true,
                  "description": "Size of output features",
                  "min": 1
                },
                {
                  "name": "bias",
                  "type": "boolean",
                  "defaultValue": true,
                  "required": false,
                  "description": "If set to False, the layer will not learn an additive bias"
                }
              ]
            },
            "parentId": "text_encoder.block"
          }
        },
        {
          "node_id": "python@text_encoder.block#0",
          "kind": "layer",
          "op": "Python",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "python",
              "name": "Python",
              "displayName": "Python",
              "description": "A statement from the source file that has no graph equivalent. Its code is kept verbatim and its shape is unknown until the model is traced.",
              "icon": "Hash",
              "category": "misc",
              "parameters": []
            },
            "parentId": "text_encoder.block"
          }
        },
        {
          "node_id": "text_encoder.block.key",
          "kind": "layer",
          "op": "Linear",
          "params": {
            "in_features": 8,
            "out_features": 8
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "linear",
              "name": "Linear",
              "displayName": "Linear",
              "description": "Fully Connected Layer",
              "icon": "Minus",
              "category": "linear",
              "parameters": [
                {
                  "name": "in_features",
                  "type": "number",
                  "defaultValue": 512,
                  "required": true,
                  "description": "Size of input features",
                  "min": 1
                },
                {
                  "name": "out_features",
                  "type": "number",
                  "defaultValue": 256,
                  "required": true,
                  "description": "Size of output features",
                  "min": 1
                },
                {
                  "name": "bias",
                  "type": "boolean",
                  "defaultValue": true,
                  "required": false,
                  "description": "If set to False, the layer will not learn an additive bias"
                }
              ]
            },
            "parentId": "text_encoder.block"
          }
        },
        {
          "node_id": "python@text_encoder.block#1",
          "kind": "layer",
          "op": "Python",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "python",
              "name": "Python",
              "displayName": "Python",
              "description": "A statement from the source file that has no graph equivalent. Its code is kept verbatim and its shape is unknown until the model is traced.",
              "icon": "Hash",
              "category": "misc",
              "parameters": []
            },
            "parentId": "text_encoder.block"
          }
        },
        {
          "node_id": "div@text_encoder.block#0",
          "kind": "layer",
          "op": "torch.div",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "div",
              "name": "torch.div",
              "displayName": "torch.div",
              "description": "PyTorch div operation",
              "icon": "Activity",
              "category": "tensor",
              "parameters": [
                {
                  "name": "dim",
                  "type": "string",
                  "defaultValue": "",
                  "required": false,
                  "description": "Dimension(s) to apply the operation on"
                }
              ]
            },
            "parentId": "text_encoder.block"
          }
        },
        {
          "node_id": "python@text_encoder.block#3",
          "kind": "layer",
          "op": "Python",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "python",
              "name": "Python",
              "displayName": "Python",
              "description": "A statement from the source file that has no graph equivalent. Its code is kept verbatim and its shape is unknown until the model is traced.",
              "icon": "Hash",
              "category": "misc",
              "parameters": []
            },
            "parentId": "text_encoder.block"
          }
        },
        {
          "node_id": "text_encoder.block.value",
          "kind": "layer",
          "op": "Linear",
          "params": {
            "in_features": 8,
            "out_features": 8
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "linear",
              "name": "Linear",
              "displayName": "Linear",
              "description": "Fully Connected Layer",
              "icon": "Minus",
              "category": "linear",
              "parameters": [
                {
                  "name": "in_features",
                  "type": "number",
                  "defaultValue": 512,
                  "required": true,
                  "description": "Size of input features",
                  "min": 1
                },
                {
                  "name": "out_features",
                  "type": "number",
                  "defaultValue": 256,
                  "required": true,
                  "description": "Size of output features",
                  "min": 1
                },
                {
                  "name": "bias",
                  "type": "boolean",
                  "defaultValue": true,
                  "required": false,
                  "description": "If set to False, the layer will not learn an additive bias"
                }
              ]
            },
            "parentId": "text_encoder.block"
          }
        },
        {
          "node_id": "python@text_encoder.block#2",
          "kind": "layer",
          "op": "Python",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "python",
              "name": "Python",
              "displayName": "Python",
              "description": "A statement from the source file that has no graph equivalent. Its code is kept verbatim and its shape is unknown until the model is traced.",
              "icon": "Hash",
              "category": "misc",
              "parameters": []
            },
            "parentId": "text_encoder.block"
          }
        },
        {
          "node_id": "text_encoder.block.softmax",
          "kind": "layer",
          "op": "Softmax",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "softmax",
              "name": "Softmax",
              "displayName": "Softmax",
              "description": "Softmax over a dimension",
              "icon": "TrendingUp",
              "category": "activation",
              "parameters": [
                {
                  "name": "dim",
                  "type": "number",
                  "defaultValue": 1,
                  "required": true,
                  "description": "Dimension along which Softmax is computed"
                }
              ]
            },
            "parentId": "text_encoder.block"
          }
        },
        {
          "node_id": "python@text_encoder.block#4",
          "kind": "layer",
          "op": "Python",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "python",
              "name": "Python",
              "displayName": "Python",
              "description": "A statement from the source file that has no graph equivalent. Its code is kept verbatim and its shape is unknown until the model is traced.",
              "icon": "Hash",
              "category": "misc",
              "parameters": []
            },
            "parentId": "text_encoder.block"
          }
        },
        {
          "node_id": "text_encoder.block.project",
          "kind": "layer",
          "op": "Linear",
          "params": {
            "in_features": 8,
            "out_features": 8
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "linear",
              "name": "Linear",
              "displayName": "Linear",
              "description": "Fully Connected Layer",
              "icon": "Minus",
              "category": "linear",
              "parameters": [
                {
                  "name": "in_features",
                  "type": "number",
                  "defaultValue": 512,
                  "required": true,
                  "description": "Size of input features",
                  "min": 1
                },
                {
                  "name": "out_features",
                  "type": "number",
                  "defaultValue": 256,
                  "required": true,
                  "description": "Size of output features",
                  "min": 1
                },
                {
                  "name": "bias",
                  "type": "boolean",
                  "defaultValue": true,
                  "required": false,
                  "description": "If set to False, the layer will not learn an additive bias"
                }
              ]
            },
            "parentId": "text_encoder.block"
          }
        },
        {
          "node_id": "add@text_encoder.block#0",
          "kind": "layer",
          "op": "torch.add",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "add",
              "name": "torch.add",
              "displayName": "torch.add",
              "description": "PyTorch add operation",
              "icon": "Activity",
              "category": "tensor",
              "parameters": [
                {
                  "name": "dim",
                  "type": "string",
                  "defaultValue": "",
                  "required": false,
                  "description": "Dimension(s) to apply the operation on"
                }
              ]
            },
            "parentId": "text_encoder.block"
          }
        },
        {
          "node_id": "text_encoder.block.ff_norm",
          "kind": "layer",
          "op": "LayerNorm",
          "params": {
            "normalized_shape": 8
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "layernorm",
              "name": "LayerNorm",
              "displayName": "LayerNorm",
              "description": "Layer Normalization",
              "icon": "Layers",
              "category": "norm",
              "parameters": [
                {
                  "name": "normalized_shape",
                  "type": "string",
                  "defaultValue": "512",
                  "required": true,
                  "description": "Input shape for normalization (comma-separated for multi-dim, e.g., 512)"
                },
                {
                  "name": "eps",
                  "type": "number",
                  "defaultValue": 0.00001,
                  "required": false,
                  "description": "Value for numerical stability",
                  "min": 0
                },
                {
                  "name": "elementwise_affine",
                  "type": "boolean",
                  "defaultValue": true,
                  "required": false,
                  "description": "If True, learnable affine parameters"
                }
              ]
            },
            "parentId": "text_encoder.block"
          }
        },
        {
          "node_id": "text_encoder.block.up",
          "kind": "layer",
          "op": "Linear",
          "params": {
            "in_features": 8,
            "out_features": 32
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "linear",
              "name": "Linear",
              "displayName": "Linear",
              "description": "Fully Connected Layer",
              "icon": "Minus",
              "category": "linear",
              "parameters": [
                {
                  "name": "in_features",
                  "type": "number",
                  "defaultValue": 512,
                  "required": true,
                  "description": "Size of input features",
                  "min": 1
                },
                {
                  "name": "out_features",
                  "type": "number",
                  "defaultValue": 256,
                  "required": true,
                  "description": "Size of output features",
                  "min": 1
                },
                {
                  "name": "bias",
                  "type": "boolean",
                  "defaultValue": true,
                  "required": false,
                  "description": "If set to False, the layer will not learn an additive bias"
                }
              ]
            },
            "parentId": "text_encoder.block"
          }
        },
        {
          "node_id": "text_encoder.block.gelu",
          "kind": "layer",
          "op": "GELU",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "gelu",
              "name": "GELU",
              "displayName": "GELU",
              "description": "Gaussian Error Linear Unit",
              "icon": "TrendingUp",
              "category": "activation",
              "parameters": [
                {
                  "name": "approximate",
                  "type": "select",
                  "defaultValue": "none",
                  "required": false,
                  "description": "The gelu approximation algorithm to use: 'none' or 'tanh'",
                  "options": [
                    "none",
                    "tanh"
                  ]
                }
              ]
            },
            "parentId": "text_encoder.block"
          }
        },
        {
          "node_id": "text_encoder.block.down",
          "kind": "layer",
          "op": "Linear",
          "params": {
            "in_features": 32,
            "out_features": 8
          },
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "linear",
              "name": "Linear",
              "displayName": "Linear",
              "description": "Fully Connected Layer",
              "icon": "Minus",
              "category": "linear",
              "parameters": [
                {
                  "name": "in_features",
                  "type": "number",
                  "defaultValue": 512,
                  "required": true,
                  "description": "Size of input features",
                  "min": 1
                },
                {
                  "name": "out_features",
                  "type": "number",
                  "defaultValue": 256,
                  "required": true,
                  "description": "Size of output features",
                  "min": 1
                },
                {
                  "name": "bias",
                  "type": "boolean",
                  "defaultValue": true,
                  "required": false,
                  "description": "If set to False, the layer will not learn an additive bias"
                }
              ]
            },
            "parentId": "text_encoder.block"
          }
        },
        {
          "node_id": "add@text_encoder.block#1",
          "kind": "layer",
          "op": "torch.add",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "add",
              "name": "torch.add",
              "displayName": "torch.add",
              "description": "PyTorch add operation",
              "icon": "Activity",
              "category": "tensor",
              "parameters": [
                {
                  "name": "dim",
                  "type": "string",
                  "defaultValue": "",
                  "required": false,
                  "description": "Dimension(s) to apply the operation on"
                }
              ]
            },
            "parentId": "text_encoder.block"
          }
        },
        {
          "node_id": "similarity.log_scale",
          "kind": "layer",
          "op": "Parameter",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "parameter",
              "description": "",
              "category": "misc",
              "icon": "Box",
              "parameters": [],
              "name": "Parameter",
              "displayName": "Parameter"
            },
            "parentId": "similarity"
          }
        },
        {
          "node_id": "mul@similarity#0",
          "kind": "layer",
          "op": "torch.mul",
          "params": {},
          "in_ports": [
            "x"
          ],
          "out_ports": [
            "y"
          ],
          "metadata": {
            "layerType": {
              "id": "mul",
              "name": "torch.mul",
              "displayName": "torch.mul",
              "description": "PyTorch mul operation",
              "icon": "Activity",
              "category": "tensor",
              "parameters": [
                {
                  "name": "dim",
                  "type": "string",
                  "defaultValue": "",
                  "required": false,
                  "description": "Dimension(s) to apply the operation on"
                }
              ]
            },
            "parentId": "similarity"
          }
        }
      ],
      "edges": [
        {
          "edge_id": "edge-1",
          "source_node_id": "image_encoder.block.norm",
          "target_node_id": "image_encoder.block.query",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-2",
          "source_node_id": "image_encoder.block.query",
          "target_node_id": "python@image_encoder.block#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-3",
          "source_node_id": "image_encoder.block.norm",
          "target_node_id": "image_encoder.block.key",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-4",
          "source_node_id": "image_encoder.block.key",
          "target_node_id": "python@image_encoder.block#1",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-5",
          "source_node_id": "image_encoder.block.norm",
          "target_node_id": "image_encoder.block.value",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-6",
          "source_node_id": "image_encoder.block.value",
          "target_node_id": "python@image_encoder.block#2",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-7",
          "source_node_id": "python@image_encoder.block#0",
          "target_node_id": "div@image_encoder.block#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-8",
          "source_node_id": "python@image_encoder.block#1",
          "target_node_id": "div@image_encoder.block#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-9",
          "source_node_id": "div@image_encoder.block#0",
          "target_node_id": "python@image_encoder.block#3",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-10",
          "source_node_id": "python@image_encoder.block#3",
          "target_node_id": "image_encoder.block.softmax",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-11",
          "source_node_id": "image_encoder.block.softmax",
          "target_node_id": "python@image_encoder.block#4",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-12",
          "source_node_id": "python@image_encoder.block#2",
          "target_node_id": "python@image_encoder.block#4",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-13",
          "source_node_id": "python@image_encoder.block#4",
          "target_node_id": "image_encoder.block.project",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-14",
          "source_node_id": "image_encoder.block.project",
          "target_node_id": "add@image_encoder.block#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-15",
          "source_node_id": "add@image_encoder.block#0",
          "target_node_id": "image_encoder.block.ff_norm",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-16",
          "source_node_id": "image_encoder.block.ff_norm",
          "target_node_id": "image_encoder.block.up",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-17",
          "source_node_id": "image_encoder.block.up",
          "target_node_id": "image_encoder.block.gelu",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-18",
          "source_node_id": "image_encoder.block.gelu",
          "target_node_id": "image_encoder.block.down",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-19",
          "source_node_id": "add@image_encoder.block#0",
          "target_node_id": "add@image_encoder.block#1",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-20",
          "source_node_id": "image_encoder.block.down",
          "target_node_id": "add@image_encoder.block#1",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-21",
          "source_node_id": "image_encoder.patches",
          "target_node_id": "flatten@image_encoder#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-22",
          "source_node_id": "flatten@image_encoder#0",
          "target_node_id": "python@image_encoder#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-23",
          "source_node_id": "image_encoder.class_token",
          "target_node_id": "cat@image_encoder#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-24",
          "source_node_id": "python@image_encoder#0",
          "target_node_id": "cat@image_encoder#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-25",
          "source_node_id": "cat@image_encoder#0",
          "target_node_id": "add@image_encoder#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-26",
          "source_node_id": "image_encoder.positions",
          "target_node_id": "add@image_encoder#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-27",
          "source_node_id": "add@image_encoder#0",
          "target_node_id": "image_encoder.pre_norm",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-28",
          "source_node_id": "image_encoder.pre_norm",
          "target_node_id": "image_encoder.block.norm",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-29",
          "source_node_id": "image_encoder.pre_norm",
          "target_node_id": "python@image_encoder.block#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-30",
          "source_node_id": "image_encoder.pre_norm",
          "target_node_id": "python@image_encoder.block#1",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-31",
          "source_node_id": "image_encoder.pre_norm",
          "target_node_id": "python@image_encoder.block#2",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-32",
          "source_node_id": "image_encoder.pre_norm",
          "target_node_id": "python@image_encoder.block#3",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-33",
          "source_node_id": "image_encoder.pre_norm",
          "target_node_id": "python@image_encoder.block#4",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-34",
          "source_node_id": "image_encoder.pre_norm",
          "target_node_id": "add@image_encoder.block#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-35",
          "source_node_id": "image_encoder.pre_norm",
          "target_node_id": "image_encoder.block",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-36",
          "source_node_id": "add@image_encoder.block#1",
          "target_node_id": "image_encoder.post_norm",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-37",
          "source_node_id": "image_encoder.block",
          "target_node_id": "image_encoder.post_norm",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-38",
          "source_node_id": "image_encoder.post_norm",
          "target_node_id": "image_encoder.project",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-39",
          "source_node_id": "image_encoder.project",
          "target_node_id": "python@image_encoder#1",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-40",
          "source_node_id": "text_encoder.block.norm",
          "target_node_id": "text_encoder.block.query",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-41",
          "source_node_id": "text_encoder.block.query",
          "target_node_id": "python@text_encoder.block#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-42",
          "source_node_id": "text_encoder.block.norm",
          "target_node_id": "text_encoder.block.key",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-43",
          "source_node_id": "text_encoder.block.key",
          "target_node_id": "python@text_encoder.block#1",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-44",
          "source_node_id": "text_encoder.block.norm",
          "target_node_id": "text_encoder.block.value",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-45",
          "source_node_id": "text_encoder.block.value",
          "target_node_id": "python@text_encoder.block#2",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-46",
          "source_node_id": "python@text_encoder.block#0",
          "target_node_id": "div@text_encoder.block#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-47",
          "source_node_id": "python@text_encoder.block#1",
          "target_node_id": "div@text_encoder.block#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-48",
          "source_node_id": "div@text_encoder.block#0",
          "target_node_id": "python@text_encoder.block#3",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-49",
          "source_node_id": "python@text_encoder.block#3",
          "target_node_id": "text_encoder.block.softmax",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-50",
          "source_node_id": "text_encoder.block.softmax",
          "target_node_id": "python@text_encoder.block#4",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-51",
          "source_node_id": "python@text_encoder.block#2",
          "target_node_id": "python@text_encoder.block#4",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-52",
          "source_node_id": "python@text_encoder.block#4",
          "target_node_id": "text_encoder.block.project",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-53",
          "source_node_id": "text_encoder.block.project",
          "target_node_id": "add@text_encoder.block#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-54",
          "source_node_id": "add@text_encoder.block#0",
          "target_node_id": "text_encoder.block.ff_norm",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-55",
          "source_node_id": "text_encoder.block.ff_norm",
          "target_node_id": "text_encoder.block.up",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-56",
          "source_node_id": "text_encoder.block.up",
          "target_node_id": "text_encoder.block.gelu",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-57",
          "source_node_id": "text_encoder.block.gelu",
          "target_node_id": "text_encoder.block.down",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-58",
          "source_node_id": "add@text_encoder.block#0",
          "target_node_id": "add@text_encoder.block#1",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-59",
          "source_node_id": "text_encoder.block.down",
          "target_node_id": "add@text_encoder.block#1",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-60",
          "source_node_id": "text_encoder.tokens",
          "target_node_id": "add@text_encoder#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-61",
          "source_node_id": "text_encoder.positions",
          "target_node_id": "add@text_encoder#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-62",
          "source_node_id": "add@text_encoder#0",
          "target_node_id": "text_encoder.block.norm",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-63",
          "source_node_id": "add@text_encoder#0",
          "target_node_id": "python@text_encoder.block#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-64",
          "source_node_id": "add@text_encoder#0",
          "target_node_id": "python@text_encoder.block#1",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-65",
          "source_node_id": "add@text_encoder#0",
          "target_node_id": "python@text_encoder.block#2",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-66",
          "source_node_id": "add@text_encoder#0",
          "target_node_id": "python@text_encoder.block#3",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-67",
          "source_node_id": "add@text_encoder#0",
          "target_node_id": "python@text_encoder.block#4",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-68",
          "source_node_id": "add@text_encoder#0",
          "target_node_id": "add@text_encoder.block#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-69",
          "source_node_id": "add@text_encoder#0",
          "target_node_id": "text_encoder.block",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-70",
          "source_node_id": "add@text_encoder.block#1",
          "target_node_id": "text_encoder.norm",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-71",
          "source_node_id": "text_encoder.block",
          "target_node_id": "text_encoder.norm",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-72",
          "source_node_id": "text_encoder.norm",
          "target_node_id": "text_encoder.project",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-73",
          "source_node_id": "text_encoder.project",
          "target_node_id": "python@text_encoder#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-74",
          "source_node_id": "similarity.log_scale",
          "target_node_id": "mul@similarity#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-75",
          "source_node_id": "input",
          "target_node_id": "image_encoder.patches",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-76",
          "source_node_id": "input",
          "target_node_id": "cat@image_encoder#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-77",
          "source_node_id": "input",
          "target_node_id": "image_encoder",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-78",
          "source_node_id": "input",
          "target_node_id": "text_encoder.tokens",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-79",
          "source_node_id": "input",
          "target_node_id": "text_encoder",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-80",
          "source_node_id": "python@image_encoder#1",
          "target_node_id": "mul@similarity#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-81",
          "source_node_id": "image_encoder",
          "target_node_id": "similarity",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-82",
          "source_node_id": "python@text_encoder#0",
          "target_node_id": "mul@similarity#0",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-83",
          "source_node_id": "text_encoder",
          "target_node_id": "similarity",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-84",
          "source_node_id": "mul@similarity#0",
          "target_node_id": "output",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        },
        {
          "edge_id": "edge-85",
          "source_node_id": "similarity",
          "target_node_id": "output",
          "source_port": "y",
          "target_port": "x",
          "metadata": {}
        }
      ],
      "inputs": [],
      "modules": [],
      "operations": [],
      "metadata": {}
    },
    "view": {
      "graph_id": "snapshot",
      "node_positions": {
        "input": {
          "x": 0,
          "y": 160
        },
        "image_encoder": {
          "x": 340,
          "y": 160
        },
        "text_encoder": {
          "x": 680,
          "y": 160
        },
        "similarity": {
          "x": 1020,
          "y": 160
        },
        "output": {
          "x": 1360,
          "y": 160
        },
        "image_encoder.patches": {
          "x": 24,
          "y": 214
        },
        "flatten@image_encoder#0": {
          "x": 24,
          "y": 364
        },
        "python@image_encoder#0": {
          "x": 24,
          "y": 514
        },
        "image_encoder.class_token": {
          "x": 24,
          "y": 664
        },
        "cat@image_encoder#0": {
          "x": 24,
          "y": 814
        },
        "image_encoder.positions": {
          "x": 24,
          "y": 964
        },
        "add@image_encoder#0": {
          "x": 24,
          "y": 1114
        },
        "image_encoder.pre_norm": {
          "x": 24,
          "y": 1264
        },
        "image_encoder.block": {
          "x": 24,
          "y": 1414
        },
        "image_encoder.post_norm": {
          "x": 24,
          "y": 1564
        },
        "image_encoder.project": {
          "x": 24,
          "y": 1714
        },
        "python@image_encoder#1": {
          "x": 24,
          "y": 1864
        },
        "image_encoder.block.norm": {
          "x": 24,
          "y": 214
        },
        "image_encoder.block.query": {
          "x": 24,
          "y": 364
        },
        "python@image_encoder.block#0": {
          "x": 24,
          "y": 514
        },
        "image_encoder.block.key": {
          "x": 24,
          "y": 664
        },
        "python@image_encoder.block#1": {
          "x": 24,
          "y": 814
        },
        "div@image_encoder.block#0": {
          "x": 24,
          "y": 964
        },
        "python@image_encoder.block#3": {
          "x": 24,
          "y": 1114
        },
        "image_encoder.block.value": {
          "x": 24,
          "y": 1264
        },
        "python@image_encoder.block#2": {
          "x": 24,
          "y": 1414
        },
        "image_encoder.block.softmax": {
          "x": 24,
          "y": 1564
        },
        "python@image_encoder.block#4": {
          "x": 24,
          "y": 1714
        },
        "image_encoder.block.project": {
          "x": 24,
          "y": 1864
        },
        "add@image_encoder.block#0": {
          "x": 24,
          "y": 2014
        },
        "image_encoder.block.ff_norm": {
          "x": 24,
          "y": 2164
        },
        "image_encoder.block.up": {
          "x": 24,
          "y": 2314
        },
        "image_encoder.block.gelu": {
          "x": 24,
          "y": 2464
        },
        "image_encoder.block.down": {
          "x": 24,
          "y": 2614
        },
        "add@image_encoder.block#1": {
          "x": 24,
          "y": 2764
        },
        "text_encoder.tokens": {
          "x": 24,
          "y": 214
        },
        "text_encoder.positions": {
          "x": 24,
          "y": 364
        },
        "add@text_encoder#0": {
          "x": 24,
          "y": 514
        },
        "text_encoder.block": {
          "x": 24,
          "y": 664
        },
        "text_encoder.norm": {
          "x": 24,
          "y": 814
        },
        "text_encoder.project": {
          "x": 24,
          "y": 964
        },
        "python@text_encoder#0": {
          "x": 24,
          "y": 1114
        },
        "text_encoder.block.norm": {
          "x": 24,
          "y": 214
        },
        "text_encoder.block.query": {
          "x": 24,
          "y": 364
        },
        "python@text_encoder.block#0": {
          "x": 24,
          "y": 514
        },
        "text_encoder.block.key": {
          "x": 24,
          "y": 664
        },
        "python@text_encoder.block#1": {
          "x": 24,
          "y": 814
        },
        "div@text_encoder.block#0": {
          "x": 24,
          "y": 964
        },
        "python@text_encoder.block#3": {
          "x": 24,
          "y": 1114
        },
        "text_encoder.block.value": {
          "x": 24,
          "y": 1264
        },
        "python@text_encoder.block#2": {
          "x": 24,
          "y": 1414
        },
        "text_encoder.block.softmax": {
          "x": 24,
          "y": 1564
        },
        "python@text_encoder.block#4": {
          "x": 24,
          "y": 1714
        },
        "text_encoder.block.project": {
          "x": 24,
          "y": 1864
        },
        "add@text_encoder.block#0": {
          "x": 24,
          "y": 2014
        },
        "text_encoder.block.ff_norm": {
          "x": 24,
          "y": 2164
        },
        "text_encoder.block.up": {
          "x": 24,
          "y": 2314
        },
        "text_encoder.block.gelu": {
          "x": 24,
          "y": 2464
        },
        "text_encoder.block.down": {
          "x": 24,
          "y": 2614
        },
        "add@text_encoder.block#1": {
          "x": 24,
          "y": 2764
        },
        "similarity.log_scale": {
          "x": 24,
          "y": 214
        },
        "mul@similarity#0": {
          "x": 24,
          "y": 364
        }
      },
      "collapsed_modules": [
        "image_encoder",
        "text_encoder",
        "similarity",
        "image_encoder.block",
        "text_encoder.block"
      ],
      "selection": [],
      "layout": {}
    }
  },
  "snapshotId": "snapshot-3befe3beceb08080",
  "collaboration": {
    "walkthrough": {
      "title": "Meet in a shared image–text space",
      "steps": [
        {
          "id": "image",
          "title": "Encode the image independently",
          "note": "Four 4 × 4 RGB patches become width-eight tokens. A class token, learned positions and one bidirectional Transformer produce a pooled image representation.",
          "view": {
            "camera": {
              "x": 308.5,
              "y": -18,
              "z": 1.25
            },
            "nodePositions": {
              "input": {
                "x": 0,
                "y": 160
              },
              "image_encoder": {
                "x": 340,
                "y": 160
              },
              "text_encoder": {
                "x": 680,
                "y": 160
              },
              "similarity": {
                "x": 1020,
                "y": 160
              },
              "output": {
                "x": 1360,
                "y": 160
              },
              "image_encoder.patches": {
                "x": 24,
                "y": 214
              },
              "flatten@image_encoder#0": {
                "x": 24,
                "y": 364
              },
              "python@image_encoder#0": {
                "x": 24,
                "y": 514
              },
              "image_encoder.class_token": {
                "x": 24,
                "y": 664
              },
              "cat@image_encoder#0": {
                "x": 24,
                "y": 814
              },
              "image_encoder.positions": {
                "x": 24,
                "y": 964
              },
              "add@image_encoder#0": {
                "x": 24,
                "y": 1114
              },
              "image_encoder.pre_norm": {
                "x": 24,
                "y": 1264
              },
              "image_encoder.block": {
                "x": 24,
                "y": 1414
              },
              "image_encoder.post_norm": {
                "x": 24,
                "y": 1564
              },
              "image_encoder.project": {
                "x": 24,
                "y": 1714
              },
              "python@image_encoder#1": {
                "x": 24,
                "y": 1864
              },
              "image_encoder.block.norm": {
                "x": 24,
                "y": 214
              },
              "image_encoder.block.query": {
                "x": 24,
                "y": 364
              },
              "python@image_encoder.block#0": {
                "x": 24,
                "y": 514
              },
              "image_encoder.block.key": {
                "x": 24,
                "y": 664
              },
              "python@image_encoder.block#1": {
                "x": 24,
                "y": 814
              },
              "div@image_encoder.block#0": {
                "x": 24,
                "y": 964
              },
              "python@image_encoder.block#3": {
                "x": 24,
                "y": 1114
              },
              "image_encoder.block.value": {
                "x": 24,
                "y": 1264
              },
              "python@image_encoder.block#2": {
                "x": 24,
                "y": 1414
              },
              "image_encoder.block.softmax": {
                "x": 24,
                "y": 1564
              },
              "python@image_encoder.block#4": {
                "x": 24,
                "y": 1714
              },
              "image_encoder.block.project": {
                "x": 24,
                "y": 1864
              },
              "add@image_encoder.block#0": {
                "x": 24,
                "y": 2014
              },
              "image_encoder.block.ff_norm": {
                "x": 24,
                "y": 2164
              },
              "image_encoder.block.up": {
                "x": 24,
                "y": 2314
              },
              "image_encoder.block.gelu": {
                "x": 24,
                "y": 2464
              },
              "image_encoder.block.down": {
                "x": 24,
                "y": 2614
              },
              "add@image_encoder.block#1": {
                "x": 24,
                "y": 2764
              },
              "text_encoder.tokens": {
                "x": 24,
                "y": 214
              },
              "text_encoder.positions": {
                "x": 24,
                "y": 364
              },
              "add@text_encoder#0": {
                "x": 24,
                "y": 514
              },
              "text_encoder.block": {
                "x": 24,
                "y": 664
              },
              "text_encoder.norm": {
                "x": 24,
                "y": 814
              },
              "text_encoder.project": {
                "x": 24,
                "y": 964
              },
              "python@text_encoder#0": {
                "x": 24,
                "y": 1114
              },
              "text_encoder.block.norm": {
                "x": 24,
                "y": 214
              },
              "text_encoder.block.query": {
                "x": 24,
                "y": 364
              },
              "python@text_encoder.block#0": {
                "x": 24,
                "y": 514
              },
              "text_encoder.block.key": {
                "x": 24,
                "y": 664
              },
              "python@text_encoder.block#1": {
                "x": 24,
                "y": 814
              },
              "div@text_encoder.block#0": {
                "x": 24,
                "y": 964
              },
              "python@text_encoder.block#3": {
                "x": 24,
                "y": 1114
              },
              "text_encoder.block.value": {
                "x": 24,
                "y": 1264
              },
              "python@text_encoder.block#2": {
                "x": 24,
                "y": 1414
              },
              "text_encoder.block.softmax": {
                "x": 24,
                "y": 1564
              },
              "python@text_encoder.block#4": {
                "x": 24,
                "y": 1714
              },
              "text_encoder.block.project": {
                "x": 24,
                "y": 1864
              },
              "add@text_encoder.block#0": {
                "x": 24,
                "y": 2014
              },
              "text_encoder.block.ff_norm": {
                "x": 24,
                "y": 2164
              },
              "text_encoder.block.up": {
                "x": 24,
                "y": 2314
              },
              "text_encoder.block.gelu": {
                "x": 24,
                "y": 2464
              },
              "text_encoder.block.down": {
                "x": 24,
                "y": 2614
              },
              "add@text_encoder.block#1": {
                "x": 24,
                "y": 2764
              },
              "similarity.log_scale": {
                "x": 24,
                "y": 214
              },
              "mul@similarity#0": {
                "x": 24,
                "y": 364
              }
            },
            "expandedModuleIds": [
              "image_encoder"
            ],
            "selectedNodeIds": [
              "image_encoder.patches"
            ],
            "viewport": {
              "width": 1100,
              "height": 700
            }
          },
          "anchors": [
            {
              "target": {
                "kind": "node",
                "nodeId": "image_encoder.patches"
              },
              "snapshotId": "snapshot-3befe3beceb08080",
              "exportedAt": "2026-09-17T06:47:49.423016+00:00",
              "modelName": "TinyCLIP",
              "context": "{\"connections\":[\"{\\\"kind\\\":\\\"edge\\\",\\\"source\\\":\\\"image_encoder.patches\\\",\\\"sourcePort\\\":\\\"y\\\",\\\"target\\\":\\\"flatten@image_encoder#0\\\",\\\"targetPort\\\":\\\"x\\\"}\",\"{\\\"kind\\\":\\\"edge\\\",\\\"source\\\":\\\"input\\\",\\\"sourcePort\\\":\\\"y\\\",\\\"target\\\":\\\"image_encoder.patches\\\",\\\"targetPort\\\":\\\"x\\\"}\"],\"contents\":[],\"node\":{\"id\":\"image_encoder.patches\",\"kind\":\"layer\",\"op\":\"Conv2d\",\"params\":{\"bias\":false,\"in_channels\":3,\"kernel_size\":4,\"out_channels\":8,\"stride\":4},\"parent\":\"image_encoder\"}}"
            }
          ]
        },
        {
          "id": "text",
          "title": "Encode the caption with causal attention",
          "note": "A separate text Transformer processes four token IDs with a causal mask. The last position stands for EOS and pools the preceding text. Neither encoder reads the other modality.",
          "view": {
            "camera": {
              "x": 308.5,
              "y": 6,
              "z": 1.25
            },
            "nodePositions": {
              "input": {
                "x": 0,
                "y": 160
              },
              "image_encoder": {
                "x": 340,
                "y": 160
              },
              "text_encoder": {
                "x": 680,
                "y": 160
              },
              "similarity": {
                "x": 1020,
                "y": 160
              },
              "output": {
                "x": 1360,
                "y": 160
              },
              "image_encoder.patches": {
                "x": 24,
                "y": 214
              },
              "flatten@image_encoder#0": {
                "x": 24,
                "y": 364
              },
              "python@image_encoder#0": {
                "x": 24,
                "y": 514
              },
              "image_encoder.class_token": {
                "x": 24,
                "y": 664
              },
              "cat@image_encoder#0": {
                "x": 24,
                "y": 814
              },
              "image_encoder.positions": {
                "x": 24,
                "y": 964
              },
              "add@image_encoder#0": {
                "x": 24,
                "y": 1114
              },
              "image_encoder.pre_norm": {
                "x": 24,
                "y": 1264
              },
              "image_encoder.block": {
                "x": 24,
                "y": 1414
              },
              "image_encoder.post_norm": {
                "x": 24,
                "y": 1564
              },
              "image_encoder.project": {
                "x": 24,
                "y": 1714
              },
              "python@image_encoder#1": {
                "x": 24,
                "y": 1864
              },
              "image_encoder.block.norm": {
                "x": 24,
                "y": 214
              },
              "image_encoder.block.query": {
                "x": 24,
                "y": 364
              },
              "python@image_encoder.block#0": {
                "x": 24,
                "y": 514
              },
              "image_encoder.block.key": {
                "x": 24,
                "y": 664
              },
              "python@image_encoder.block#1": {
                "x": 24,
                "y": 814
              },
              "div@image_encoder.block#0": {
                "x": 24,
                "y": 964
              },
              "python@image_encoder.block#3": {
                "x": 24,
                "y": 1114
              },
              "image_encoder.block.value": {
                "x": 24,
                "y": 1264
              },
              "python@image_encoder.block#2": {
                "x": 24,
                "y": 1414
              },
              "image_encoder.block.softmax": {
                "x": 24,
                "y": 1564
              },
              "python@image_encoder.block#4": {
                "x": 24,
                "y": 1714
              },
              "image_encoder.block.project": {
                "x": 24,
                "y": 1864
              },
              "add@image_encoder.block#0": {
                "x": 24,
                "y": 2014
              },
              "image_encoder.block.ff_norm": {
                "x": 24,
                "y": 2164
              },
              "image_encoder.block.up": {
                "x": 24,
                "y": 2314
              },
              "image_encoder.block.gelu": {
                "x": 24,
                "y": 2464
              },
              "image_encoder.block.down": {
                "x": 24,
                "y": 2614
              },
              "add@image_encoder.block#1": {
                "x": 24,
                "y": 2764
              },
              "text_encoder.tokens": {
                "x": 24,
                "y": 214
              },
              "text_encoder.positions": {
                "x": 24,
                "y": 364
              },
              "add@text_encoder#0": {
                "x": 24,
                "y": 514
              },
              "text_encoder.block": {
                "x": 24,
                "y": 664
              },
              "text_encoder.norm": {
                "x": 24,
                "y": 814
              },
              "text_encoder.project": {
                "x": 24,
                "y": 964
              },
              "python@text_encoder#0": {
                "x": 24,
                "y": 1114
              },
              "text_encoder.block.norm": {
                "x": 24,
                "y": 214
              },
              "text_encoder.block.query": {
                "x": 24,
                "y": 364
              },
              "python@text_encoder.block#0": {
                "x": 24,
                "y": 514
              },
              "text_encoder.block.key": {
                "x": 24,
                "y": 664
              },
              "python@text_encoder.block#1": {
                "x": 24,
                "y": 814
              },
              "div@text_encoder.block#0": {
                "x": 24,
                "y": 964
              },
              "python@text_encoder.block#3": {
                "x": 24,
                "y": 1114
              },
              "text_encoder.block.value": {
                "x": 24,
                "y": 1264
              },
              "python@text_encoder.block#2": {
                "x": 24,
                "y": 1414
              },
              "text_encoder.block.softmax": {
                "x": 24,
                "y": 1564
              },
              "python@text_encoder.block#4": {
                "x": 24,
                "y": 1714
              },
              "text_encoder.block.project": {
                "x": 24,
                "y": 1864
              },
              "add@text_encoder.block#0": {
                "x": 24,
                "y": 2014
              },
              "text_encoder.block.ff_norm": {
                "x": 24,
                "y": 2164
              },
              "text_encoder.block.up": {
                "x": 24,
                "y": 2314
              },
              "text_encoder.block.gelu": {
                "x": 24,
                "y": 2464
              },
              "text_encoder.block.down": {
                "x": 24,
                "y": 2614
              },
              "add@text_encoder.block#1": {
                "x": 24,
                "y": 2764
              },
              "similarity.log_scale": {
                "x": 24,
                "y": 214
              },
              "mul@similarity#0": {
                "x": 24,
                "y": 364
              }
            },
            "expandedModuleIds": [
              "text_encoder"
            ],
            "selectedNodeIds": [
              "text_encoder.tokens"
            ],
            "viewport": {
              "width": 1100,
              "height": 700
            }
          },
          "anchors": [
            {
              "target": {
                "kind": "node",
                "nodeId": "text_encoder.tokens"
              },
              "snapshotId": "snapshot-3befe3beceb08080",
              "exportedAt": "2026-09-17T06:47:49.423016+00:00",
              "modelName": "TinyCLIP",
              "context": "{\"connections\":[\"{\\\"kind\\\":\\\"edge\\\",\\\"source\\\":\\\"input\\\",\\\"sourcePort\\\":\\\"y\\\",\\\"target\\\":\\\"text_encoder.tokens\\\",\\\"targetPort\\\":\\\"x\\\"}\",\"{\\\"kind\\\":\\\"edge\\\",\\\"source\\\":\\\"text_encoder.tokens\\\",\\\"sourcePort\\\":\\\"y\\\",\\\"target\\\":\\\"add@text_encoder#0\\\",\\\"targetPort\\\":\\\"x\\\"}\"],\"contents\":[],\"node\":{\"id\":\"text_encoder.tokens\",\"kind\":\"layer\",\"op\":\"Embedding\",\"params\":{\"embedding_dim\":8,\"num_embeddings\":16},\"parent\":\"text_encoder\"}}"
            }
          ]
        },
        {
          "id": "compare",
          "title": "Compare every image with every text",
          "note": "Each encoder linearly projects to four features and L2-normalizes the result. The similarity block computes all nine pairwise cosines and multiplies them by exp(log_scale), the learned inverse temperature.",
          "view": {
            "camera": {
              "x": -705.3846153846154,
              "y": -103.60839160839157,
              "z": 1.1349206349206349
            },
            "nodePositions": {
              "input": {
                "x": 0,
                "y": 160
              },
              "image_encoder": {
                "x": 340,
                "y": 160
              },
              "text_encoder": {
                "x": 680,
                "y": 160
              },
              "similarity": {
                "x": 1020,
                "y": 160
              },
              "output": {
                "x": 1360,
                "y": 160
              },
              "image_encoder.patches": {
                "x": 24,
                "y": 214
              },
              "flatten@image_encoder#0": {
                "x": 24,
                "y": 364
              },
              "python@image_encoder#0": {
                "x": 24,
                "y": 514
              },
              "image_encoder.class_token": {
                "x": 24,
                "y": 664
              },
              "cat@image_encoder#0": {
                "x": 24,
                "y": 814
              },
              "image_encoder.positions": {
                "x": 24,
                "y": 964
              },
              "add@image_encoder#0": {
                "x": 24,
                "y": 1114
              },
              "image_encoder.pre_norm": {
                "x": 24,
                "y": 1264
              },
              "image_encoder.block": {
                "x": 24,
                "y": 1414
              },
              "image_encoder.post_norm": {
                "x": 24,
                "y": 1564
              },
              "image_encoder.project": {
                "x": 24,
                "y": 1714
              },
              "python@image_encoder#1": {
                "x": 24,
                "y": 1864
              },
              "image_encoder.block.norm": {
                "x": 24,
                "y": 214
              },
              "image_encoder.block.query": {
                "x": 24,
                "y": 364
              },
              "python@image_encoder.block#0": {
                "x": 24,
                "y": 514
              },
              "image_encoder.block.key": {
                "x": 24,
                "y": 664
              },
              "python@image_encoder.block#1": {
                "x": 24,
                "y": 814
              },
              "div@image_encoder.block#0": {
                "x": 24,
                "y": 964
              },
              "python@image_encoder.block#3": {
                "x": 24,
                "y": 1114
              },
              "image_encoder.block.value": {
                "x": 24,
                "y": 1264
              },
              "python@image_encoder.block#2": {
                "x": 24,
                "y": 1414
              },
              "image_encoder.block.softmax": {
                "x": 24,
                "y": 1564
              },
              "python@image_encoder.block#4": {
                "x": 24,
                "y": 1714
              },
              "image_encoder.block.project": {
                "x": 24,
                "y": 1864
              },
              "add@image_encoder.block#0": {
                "x": 24,
                "y": 2014
              },
              "image_encoder.block.ff_norm": {
                "x": 24,
                "y": 2164
              },
              "image_encoder.block.up": {
                "x": 24,
                "y": 2314
              },
              "image_encoder.block.gelu": {
                "x": 24,
                "y": 2464
              },
              "image_encoder.block.down": {
                "x": 24,
                "y": 2614
              },
              "add@image_encoder.block#1": {
                "x": 24,
                "y": 2764
              },
              "text_encoder.tokens": {
                "x": 24,
                "y": 214
              },
              "text_encoder.positions": {
                "x": 24,
                "y": 364
              },
              "add@text_encoder#0": {
                "x": 24,
                "y": 514
              },
              "text_encoder.block": {
                "x": 24,
                "y": 664
              },
              "text_encoder.norm": {
                "x": 24,
                "y": 814
              },
              "text_encoder.project": {
                "x": 24,
                "y": 964
              },
              "python@text_encoder#0": {
                "x": 24,
                "y": 1114
              },
              "text_encoder.block.norm": {
                "x": 24,
                "y": 214
              },
              "text_encoder.block.query": {
                "x": 24,
                "y": 364
              },
              "python@text_encoder.block#0": {
                "x": 24,
                "y": 514
              },
              "text_encoder.block.key": {
                "x": 24,
                "y": 664
              },
              "python@text_encoder.block#1": {
                "x": 24,
                "y": 814
              },
              "div@text_encoder.block#0": {
                "x": 24,
                "y": 964
              },
              "python@text_encoder.block#3": {
                "x": 24,
                "y": 1114
              },
              "text_encoder.block.value": {
                "x": 24,
                "y": 1264
              },
              "python@text_encoder.block#2": {
                "x": 24,
                "y": 1414
              },
              "text_encoder.block.softmax": {
                "x": 24,
                "y": 1564
              },
              "python@text_encoder.block#4": {
                "x": 24,
                "y": 1714
              },
              "text_encoder.block.project": {
                "x": 24,
                "y": 1864
              },
              "add@text_encoder.block#0": {
                "x": 24,
                "y": 2014
              },
              "text_encoder.block.ff_norm": {
                "x": 24,
                "y": 2164
              },
              "text_encoder.block.up": {
                "x": 24,
                "y": 2314
              },
              "text_encoder.block.gelu": {
                "x": 24,
                "y": 2464
              },
              "text_encoder.block.down": {
                "x": 24,
                "y": 2614
              },
              "add@text_encoder.block#1": {
                "x": 24,
                "y": 2764
              },
              "similarity.log_scale": {
                "x": 24,
                "y": 214
              },
              "mul@similarity#0": {
                "x": 24,
                "y": 364
              }
            },
            "expandedModuleIds": [
              "similarity"
            ],
            "selectedNodeIds": [
              "similarity"
            ],
            "viewport": {
              "width": 1100,
              "height": 700
            }
          },
          "anchors": [
            {
              "target": {
                "kind": "node",
                "nodeId": "similarity"
              },
              "snapshotId": "snapshot-3befe3beceb08080",
              "exportedAt": "2026-09-17T06:47:49.423016+00:00",
              "modelName": "TinyCLIP",
              "context": "{\"connections\":[\"{\\\"kind\\\":\\\"edge\\\",\\\"source\\\":\\\"image_encoder\\\",\\\"sourcePort\\\":\\\"y\\\",\\\"target\\\":\\\"similarity\\\",\\\"targetPort\\\":\\\"x\\\"}\",\"{\\\"kind\\\":\\\"edge\\\",\\\"source\\\":\\\"mul@similarity#0\\\",\\\"sourcePort\\\":\\\"y\\\",\\\"target\\\":\\\"output\\\",\\\"targetPort\\\":\\\"x\\\"}\",\"{\\\"kind\\\":\\\"edge\\\",\\\"source\\\":\\\"python@image_encoder#1\\\",\\\"sourcePort\\\":\\\"y\\\",\\\"target\\\":\\\"mul@similarity#0\\\",\\\"targetPort\\\":\\\"x\\\"}\",\"{\\\"kind\\\":\\\"edge\\\",\\\"source\\\":\\\"python@text_encoder#0\\\",\\\"sourcePort\\\":\\\"y\\\",\\\"target\\\":\\\"mul@similarity#0\\\",\\\"targetPort\\\":\\\"x\\\"}\",\"{\\\"kind\\\":\\\"edge\\\",\\\"source\\\":\\\"similarity\\\",\\\"sourcePort\\\":\\\"y\\\",\\\"target\\\":\\\"output\\\",\\\"targetPort\\\":\\\"x\\\"}\",\"{\\\"kind\\\":\\\"edge\\\",\\\"source\\\":\\\"similarity.log_scale\\\",\\\"sourcePort\\\":\\\"y\\\",\\\"target\\\":\\\"mul@similarity#0\\\",\\\"targetPort\\\":\\\"x\\\"}\",\"{\\\"kind\\\":\\\"edge\\\",\\\"source\\\":\\\"text_encoder\\\",\\\"sourcePort\\\":\\\"y\\\",\\\"target\\\":\\\"similarity\\\",\\\"targetPort\\\":\\\"x\\\"}\"],\"contents\":[\"{\\\"id\\\":\\\"mul@similarity#0\\\",\\\"kind\\\":\\\"layer\\\",\\\"op\\\":\\\"torch.mul\\\",\\\"params\\\":{},\\\"parent\\\":\\\"similarity\\\"}\",\"{\\\"id\\\":\\\"similarity.log_scale\\\",\\\"kind\\\":\\\"layer\\\",\\\"op\\\":\\\"Parameter\\\",\\\"params\\\":{},\\\"parent\\\":\\\"similarity\\\"}\"],\"node\":{\"id\":\"similarity\",\"kind\":\"module\",\"op\":\"Module\",\"params\":{}}}"
            }
          ]
        },
        {
          "id": "objective",
          "title": "Train the paired diagonal in both directions",
          "note": "The local objective averages image-to-text and text-to-image cross entropy. Diagonal targets identify supplied pairs; batch negatives supply alternatives. Gradients reach both projections and both encoders. The panel exposes pairing and temperature effects.",
          "view": {
            "camera": {
              "x": 308.5,
              "y": -1497.5,
              "z": 1.25
            },
            "nodePositions": {
              "input": {
                "x": 0,
                "y": 160
              },
              "image_encoder": {
                "x": 340,
                "y": 160
              },
              "text_encoder": {
                "x": 680,
                "y": 160
              },
              "similarity": {
                "x": 1020,
                "y": 160
              },
              "output": {
                "x": 1360,
                "y": 160
              },
              "image_encoder.patches": {
                "x": 24,
                "y": 214
              },
              "flatten@image_encoder#0": {
                "x": 24,
                "y": 364
              },
              "python@image_encoder#0": {
                "x": 24,
                "y": 514
              },
              "image_encoder.class_token": {
                "x": 24,
                "y": 664
              },
              "cat@image_encoder#0": {
                "x": 24,
                "y": 814
              },
              "image_encoder.positions": {
                "x": 24,
                "y": 964
              },
              "add@image_encoder#0": {
                "x": 24,
                "y": 1114
              },
              "image_encoder.pre_norm": {
                "x": 24,
                "y": 1264
              },
              "image_encoder.block": {
                "x": 24,
                "y": 1414
              },
              "image_encoder.post_norm": {
                "x": 24,
                "y": 1564
              },
              "image_encoder.project": {
                "x": 24,
                "y": 1714
              },
              "python@image_encoder#1": {
                "x": 24,
                "y": 1864
              },
              "image_encoder.block.norm": {
                "x": 24,
                "y": 214
              },
              "image_encoder.block.query": {
                "x": 24,
                "y": 364
              },
              "python@image_encoder.block#0": {
                "x": 24,
                "y": 514
              },
              "image_encoder.block.key": {
                "x": 24,
                "y": 664
              },
              "python@image_encoder.block#1": {
                "x": 24,
                "y": 814
              },
              "div@image_encoder.block#0": {
                "x": 24,
                "y": 964
              },
              "python@image_encoder.block#3": {
                "x": 24,
                "y": 1114
              },
              "image_encoder.block.value": {
                "x": 24,
                "y": 1264
              },
              "python@image_encoder.block#2": {
                "x": 24,
                "y": 1414
              },
              "image_encoder.block.softmax": {
                "x": 24,
                "y": 1564
              },
              "python@image_encoder.block#4": {
                "x": 24,
                "y": 1714
              },
              "image_encoder.block.project": {
                "x": 24,
                "y": 1864
              },
              "add@image_encoder.block#0": {
                "x": 24,
                "y": 2014
              },
              "image_encoder.block.ff_norm": {
                "x": 24,
                "y": 2164
              },
              "image_encoder.block.up": {
                "x": 24,
                "y": 2314
              },
              "image_encoder.block.gelu": {
                "x": 24,
                "y": 2464
              },
              "image_encoder.block.down": {
                "x": 24,
                "y": 2614
              },
              "add@image_encoder.block#1": {
                "x": 24,
                "y": 2764
              },
              "text_encoder.tokens": {
                "x": 24,
                "y": 214
              },
              "text_encoder.positions": {
                "x": 24,
                "y": 364
              },
              "add@text_encoder#0": {
                "x": 24,
                "y": 514
              },
              "text_encoder.block": {
                "x": 24,
                "y": 664
              },
              "text_encoder.norm": {
                "x": 24,
                "y": 814
              },
              "text_encoder.project": {
                "x": 24,
                "y": 964
              },
              "python@text_encoder#0": {
                "x": 24,
                "y": 1114
              },
              "text_encoder.block.norm": {
                "x": 24,
                "y": 214
              },
              "text_encoder.block.query": {
                "x": 24,
                "y": 364
              },
              "python@text_encoder.block#0": {
                "x": 24,
                "y": 514
              },
              "text_encoder.block.key": {
                "x": 24,
                "y": 664
              },
              "python@text_encoder.block#1": {
                "x": 24,
                "y": 814
              },
              "div@text_encoder.block#0": {
                "x": 24,
                "y": 964
              },
              "python@text_encoder.block#3": {
                "x": 24,
                "y": 1114
              },
              "text_encoder.block.value": {
                "x": 24,
                "y": 1264
              },
              "python@text_encoder.block#2": {
                "x": 24,
                "y": 1414
              },
              "text_encoder.block.softmax": {
                "x": 24,
                "y": 1564
              },
              "python@text_encoder.block#4": {
                "x": 24,
                "y": 1714
              },
              "text_encoder.block.project": {
                "x": 24,
                "y": 1864
              },
              "add@text_encoder.block#0": {
                "x": 24,
                "y": 2014
              },
              "text_encoder.block.ff_norm": {
                "x": 24,
                "y": 2164
              },
              "text_encoder.block.up": {
                "x": 24,
                "y": 2314
              },
              "text_encoder.block.gelu": {
                "x": 24,
                "y": 2464
              },
              "text_encoder.block.down": {
                "x": 24,
                "y": 2614
              },
              "add@text_encoder.block#1": {
                "x": 24,
                "y": 2764
              },
              "similarity.log_scale": {
                "x": 24,
                "y": 214
              },
              "mul@similarity#0": {
                "x": 24,
                "y": 364
              }
            },
            "expandedModuleIds": [
              "image_encoder"
            ],
            "selectedNodeIds": [
              "image_encoder.project"
            ],
            "viewport": {
              "width": 1100,
              "height": 700
            }
          },
          "anchors": [
            {
              "target": {
                "kind": "node",
                "nodeId": "image_encoder.project"
              },
              "snapshotId": "snapshot-3befe3beceb08080",
              "exportedAt": "2026-09-17T06:47:49.423016+00:00",
              "modelName": "TinyCLIP",
              "context": "{\"connections\":[\"{\\\"kind\\\":\\\"edge\\\",\\\"source\\\":\\\"image_encoder.post_norm\\\",\\\"sourcePort\\\":\\\"y\\\",\\\"target\\\":\\\"image_encoder.project\\\",\\\"targetPort\\\":\\\"x\\\"}\",\"{\\\"kind\\\":\\\"edge\\\",\\\"source\\\":\\\"image_encoder.project\\\",\\\"sourcePort\\\":\\\"y\\\",\\\"target\\\":\\\"python@image_encoder#1\\\",\\\"targetPort\\\":\\\"x\\\"}\"],\"contents\":[],\"node\":{\"id\":\"image_encoder.project\",\"kind\":\"layer\",\"op\":\"Linear\",\"params\":{\"bias\":false,\"in_features\":8,\"out_features\":4},\"parent\":\"image_encoder\"}}"
            }
          ]
        }
      ]
    },
    "threads": [],
    "savedViews": [
      {
        "id": "compare",
        "title": "Compare every image with every text",
        "note": "Each encoder linearly projects to four features and L2-normalizes the result. The similarity block computes all nine pairwise cosines and multiplies them by exp(log_scale), the learned inverse temperature.",
        "view": {
          "camera": {
            "x": -705.3846153846154,
            "y": -103.60839160839157,
            "z": 1.1349206349206349
          },
          "nodePositions": {
            "input": {
              "x": 0,
              "y": 160
            },
            "image_encoder": {
              "x": 340,
              "y": 160
            },
            "text_encoder": {
              "x": 680,
              "y": 160
            },
            "similarity": {
              "x": 1020,
              "y": 160
            },
            "output": {
              "x": 1360,
              "y": 160
            },
            "image_encoder.patches": {
              "x": 24,
              "y": 214
            },
            "flatten@image_encoder#0": {
              "x": 24,
              "y": 364
            },
            "python@image_encoder#0": {
              "x": 24,
              "y": 514
            },
            "image_encoder.class_token": {
              "x": 24,
              "y": 664
            },
            "cat@image_encoder#0": {
              "x": 24,
              "y": 814
            },
            "image_encoder.positions": {
              "x": 24,
              "y": 964
            },
            "add@image_encoder#0": {
              "x": 24,
              "y": 1114
            },
            "image_encoder.pre_norm": {
              "x": 24,
              "y": 1264
            },
            "image_encoder.block": {
              "x": 24,
              "y": 1414
            },
            "image_encoder.post_norm": {
              "x": 24,
              "y": 1564
            },
            "image_encoder.project": {
              "x": 24,
              "y": 1714
            },
            "python@image_encoder#1": {
              "x": 24,
              "y": 1864
            },
            "image_encoder.block.norm": {
              "x": 24,
              "y": 214
            },
            "image_encoder.block.query": {
              "x": 24,
              "y": 364
            },
            "python@image_encoder.block#0": {
              "x": 24,
              "y": 514
            },
            "image_encoder.block.key": {
              "x": 24,
              "y": 664
            },
            "python@image_encoder.block#1": {
              "x": 24,
              "y": 814
            },
            "div@image_encoder.block#0": {
              "x": 24,
              "y": 964
            },
            "python@image_encoder.block#3": {
              "x": 24,
              "y": 1114
            },
            "image_encoder.block.value": {
              "x": 24,
              "y": 1264
            },
            "python@image_encoder.block#2": {
              "x": 24,
              "y": 1414
            },
            "image_encoder.block.softmax": {
              "x": 24,
              "y": 1564
            },
            "python@image_encoder.block#4": {
              "x": 24,
              "y": 1714
            },
            "image_encoder.block.project": {
              "x": 24,
              "y": 1864
            },
            "add@image_encoder.block#0": {
              "x": 24,
              "y": 2014
            },
            "image_encoder.block.ff_norm": {
              "x": 24,
              "y": 2164
            },
            "image_encoder.block.up": {
              "x": 24,
              "y": 2314
            },
            "image_encoder.block.gelu": {
              "x": 24,
              "y": 2464
            },
            "image_encoder.block.down": {
              "x": 24,
              "y": 2614
            },
            "add@image_encoder.block#1": {
              "x": 24,
              "y": 2764
            },
            "text_encoder.tokens": {
              "x": 24,
              "y": 214
            },
            "text_encoder.positions": {
              "x": 24,
              "y": 364
            },
            "add@text_encoder#0": {
              "x": 24,
              "y": 514
            },
            "text_encoder.block": {
              "x": 24,
              "y": 664
            },
            "text_encoder.norm": {
              "x": 24,
              "y": 814
            },
            "text_encoder.project": {
              "x": 24,
              "y": 964
            },
            "python@text_encoder#0": {
              "x": 24,
              "y": 1114
            },
            "text_encoder.block.norm": {
              "x": 24,
              "y": 214
            },
            "text_encoder.block.query": {
              "x": 24,
              "y": 364
            },
            "python@text_encoder.block#0": {
              "x": 24,
              "y": 514
            },
            "text_encoder.block.key": {
              "x": 24,
              "y": 664
            },
            "python@text_encoder.block#1": {
              "x": 24,
              "y": 814
            },
            "div@text_encoder.block#0": {
              "x": 24,
              "y": 964
            },
            "python@text_encoder.block#3": {
              "x": 24,
              "y": 1114
            },
            "text_encoder.block.value": {
              "x": 24,
              "y": 1264
            },
            "python@text_encoder.block#2": {
              "x": 24,
              "y": 1414
            },
            "text_encoder.block.softmax": {
              "x": 24,
              "y": 1564
            },
            "python@text_encoder.block#4": {
              "x": 24,
              "y": 1714
            },
            "text_encoder.block.project": {
              "x": 24,
              "y": 1864
            },
            "add@text_encoder.block#0": {
              "x": 24,
              "y": 2014
            },
            "text_encoder.block.ff_norm": {
              "x": 24,
              "y": 2164
            },
            "text_encoder.block.up": {
              "x": 24,
              "y": 2314
            },
            "text_encoder.block.gelu": {
              "x": 24,
              "y": 2464
            },
            "text_encoder.block.down": {
              "x": 24,
              "y": 2614
            },
            "add@text_encoder.block#1": {
              "x": 24,
              "y": 2764
            },
            "similarity.log_scale": {
              "x": 24,
              "y": 214
            },
            "mul@similarity#0": {
              "x": 24,
              "y": 364
            }
          },
          "expandedModuleIds": [
            "similarity"
          ],
          "selectedNodeIds": [
            "similarity"
          ],
          "viewport": {
            "width": 1100,
            "height": 700
          }
        },
        "anchors": [
          {
            "target": {
              "kind": "node",
              "nodeId": "similarity"
            },
            "snapshotId": "snapshot-3befe3beceb08080",
            "exportedAt": "2026-09-17T06:47:49.423016+00:00",
            "modelName": "TinyCLIP",
            "context": "{\"connections\":[\"{\\\"kind\\\":\\\"edge\\\",\\\"source\\\":\\\"image_encoder\\\",\\\"sourcePort\\\":\\\"y\\\",\\\"target\\\":\\\"similarity\\\",\\\"targetPort\\\":\\\"x\\\"}\",\"{\\\"kind\\\":\\\"edge\\\",\\\"source\\\":\\\"mul@similarity#0\\\",\\\"sourcePort\\\":\\\"y\\\",\\\"target\\\":\\\"output\\\",\\\"targetPort\\\":\\\"x\\\"}\",\"{\\\"kind\\\":\\\"edge\\\",\\\"source\\\":\\\"python@image_encoder#1\\\",\\\"sourcePort\\\":\\\"y\\\",\\\"target\\\":\\\"mul@similarity#0\\\",\\\"targetPort\\\":\\\"x\\\"}\",\"{\\\"kind\\\":\\\"edge\\\",\\\"source\\\":\\\"python@text_encoder#0\\\",\\\"sourcePort\\\":\\\"y\\\",\\\"target\\\":\\\"mul@similarity#0\\\",\\\"targetPort\\\":\\\"x\\\"}\",\"{\\\"kind\\\":\\\"edge\\\",\\\"source\\\":\\\"similarity\\\",\\\"sourcePort\\\":\\\"y\\\",\\\"target\\\":\\\"output\\\",\\\"targetPort\\\":\\\"x\\\"}\",\"{\\\"kind\\\":\\\"edge\\\",\\\"source\\\":\\\"similarity.log_scale\\\",\\\"sourcePort\\\":\\\"y\\\",\\\"target\\\":\\\"mul@similarity#0\\\",\\\"targetPort\\\":\\\"x\\\"}\",\"{\\\"kind\\\":\\\"edge\\\",\\\"source\\\":\\\"text_encoder\\\",\\\"sourcePort\\\":\\\"y\\\",\\\"target\\\":\\\"similarity\\\",\\\"targetPort\\\":\\\"x\\\"}\"],\"contents\":[\"{\\\"id\\\":\\\"mul@similarity#0\\\",\\\"kind\\\":\\\"layer\\\",\\\"op\\\":\\\"torch.mul\\\",\\\"params\\\":{},\\\"parent\\\":\\\"similarity\\\"}\",\"{\\\"id\\\":\\\"similarity.log_scale\\\",\\\"kind\\\":\\\"layer\\\",\\\"op\\\":\\\"Parameter\\\",\\\"params\\\":{},\\\"parent\\\":\\\"similarity\\\"}\"],\"node\":{\"id\":\"similarity\",\"kind\":\"module\",\"op\":\"Module\",\"params\":{}}}"
          }
        ]
      }
    ],
    "openingViewId": "compare"
  }
}
