prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Refine docs for check_model
  Current version:
  
  > Check the consistency of a model. An exception is raised if the test fails.
  
  It would be good if we document the kind of checks done and the type of exception raised so users know what to catch for; as well as clarify that it also runs shape inference when strict is True. (Right now it says `if True, the function checks shapes can be inferred`）
  
  Should we default `strict` to `True`? @jcwchen 
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `onnx/checker.py`
  Content:
  ```
  1 # Copyright (c) ONNX Project Contributors
  2 #
  3 # SPDX-License-Identifier: Apache-2.0
  4 """Graph utilities for checking whether an ONNX proto message is legal."""
  5 
  6 from __future__ import annotations
  7 
  8 __all__ = [
  9     "check_attribute",
  10     "check_function",
  11     "check_graph",
  12     "check_model",
  13     "check_node",
  14     "check_sparse_tensor",
  15     "check_tensor",
  16     "check_value_info",
  17     "DEFAULT_CONTEXT",
  18     "ValidationError",
  19     "C",
  20     "MAXIMUM_PROTOBUF",
  21 ]
  22 
  23 import os
  24 import sys
  25 from typing import Any, Callable, TypeVar
  26 
  27 from google.protobuf.message import Message
  28 
  29 import onnx.defs
  30 import onnx.onnx_cpp2py_export.checker as C  # noqa: N812
  31 import onnx.shape_inference
  32 from onnx import (
  33     IR_VERSION,
  34     AttributeProto,
  35     FunctionProto,
  36     GraphProto,
  37     ModelProto,
  38     NodeProto,
  39     SparseTensorProto,
  40     TensorProto,
  41     ValueInfoProto,
  42     helper,
  43 )
  44 
  45 # Limitation of single protobuf file is 2GB
  46 MAXIMUM_PROTOBUF = 2000000000
  47 
  48 # TODO: This thing where we reserialize the protobuf back into the
  49 # string, only to deserialize it at the call site, is really goofy.
  50 # Stop doing that.
  51 
  52 
  53 # NB: Please don't edit this context!
  54 DEFAULT_CONTEXT = C.CheckerContext()
  55 DEFAULT_CONTEXT.ir_version = IR_VERSION
  56 # TODO: Maybe ONNX-ML should also be defaulted?
  57 DEFAULT_CONTEXT.opset_imports = {"": onnx.defs.onnx_opset_version()}
  58 
  59 
  60 FuncType = TypeVar("FuncType", bound=Callable[..., Any])
  61 
  62 
  63 def _ensure_proto_type(proto: Message, proto_type: type[Message]) -> None:
  64     if not isinstance(proto, proto_type):
  65         raise TypeError(
  66             f"The proto message needs to be of type '{proto_type.__name__}'"
  67         )
  68 
  69 
  70 def check_value_info(
  71     value_info: ValueInfoProto, ctx: C.CheckerContext = DEFAULT_CONTEXT
  72 ) -> None:
  73     _ensure_proto_type(value_info, ValueInfoProto)
  74     return C.check_value_info(value_info.SerializeToString(), ctx)
  75 
  76 
  77 def check_tensor(tensor: TensorProto, ctx: C.CheckerContext = DEFAULT_CONTEXT) -> None:
  78     _ensure_proto_type(tensor, TensorProto)
  79     return C.check_tensor(tensor.SerializeToString(), ctx)
  80 
  81 
  82 def check_attribute(
  83     attr: AttributeProto, ctx: C.CheckerContext = DEFAULT_CONTEXT
  84 ) -> None:
  85     _ensure_proto_type(attr, AttributeProto)
  86     return C.check_attribute(attr.SerializeToString(), ctx)
  87 
  88 
  89 def check_node(node: NodeProto, ctx: C.CheckerContext = DEFAULT_CONTEXT) -> None:
  90     _ensure_proto_type(node, NodeProto)
  91     return C.check_node(node.SerializeToString(), ctx)
  92 
  93 
  94 def check_function(
  95     function: FunctionProto, ctx: C.CheckerContext | None = None
  96 ) -> None:
  97     _ensure_proto_type(function, FunctionProto)
  98     if ctx is None:
  99         ctx = C.CheckerContext()
  100         ctx.ir_version = helper.find_min_ir_version_for(
  101             list(function.opset_import), True
  102         )
  103         function_opset_dic = {}
  104         for domain_version in function.opset_import:
  105             function_opset_dic[domain_version.domain] = domain_version.version
  106         ctx.opset_imports = function_opset_dic
  107     C.check_function(function.SerializeToString(), ctx)
  108 
  109 
  110 def check_graph(graph: GraphProto, ctx: C.CheckerContext = DEFAULT_CONTEXT) -> None:
  111     _ensure_proto_type(graph, GraphProto)
  112     return C.check_graph(graph.SerializeToString(), ctx)
  113 
  114 
  115 def check_sparse_tensor(
  116     sparse: SparseTensorProto, ctx: C.CheckerContext = DEFAULT_CONTEXT
  117 ) -> None:
  118     _ensure_proto_type(sparse, SparseTensorProto)
  119     C.check_sparse_tensor(sparse.SerializeToString(), ctx)
  120 
  121 
  122 def check_model(
  123     model: ModelProto | str | bytes | os.PathLike,
  124     full_check: bool = False,
  125     skip_opset_compatibility_check: bool = False,
  126 ) -> None:
  127     """Check the consistency of a model. An exception is raised if the test fails.
  128 
  129     Args:
  130         model: Model to check.
  131         full_check: If True, the function also checks for shapes that can be inferred.
  132         skip_opset_compatibility_check: If True, the function skips the check for
  133             opset compatibility.
  134     """
  135     # If model is a path instead of ModelProto
  136     if isinstance(model, (str, os.PathLike)):
  137         C.check_model_path(os.fspath(model), full_check, skip_opset_compatibility_check)
  138     else:
  139         protobuf_string = (
  140             model if isinstance(model, bytes) else model.SerializeToString()
  141         )
  142         # If the protobuf is larger than 2GB,
  143         # remind users should use the model path to check
  144         if sys.getsizeof(protobuf_string) > MAXIMUM_PROTOBUF:
  145             raise ValueError(
  146                 "This protobuf of onnx model is too large (>2GB). Call check_model with model path instead."
  147             )
  148         C.check_model(protobuf_string, full_check, skip_opset_compatibility_check)
  149 
  150 
  151 ValidationError = C.ValidationError
  152
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/onnx/checker.py b/onnx/checker.py
  --- a/onnx/checker.py
  +++ b/onnx/checker.py
  @@ -124,11 +124,20 @@
       full_check: bool = False,
       skip_opset_compatibility_check: bool = False,
   ) -> None:
  -    """Check the consistency of a model. An exception is raised if the test fails.
  +    """Check the consistency of a model.
  +
  +    An exception will be raised if the model's ir_version is not set
  +    properly or is higher than checker's ir_version, or if the model
  +    has duplicate keys in metadata_props.
  +
  +    If IR version >= 3, the model must specify opset_import.
  +    If IR version < 3, the model cannot have any opset_import specified.
   
       Args:
  -        model: Model to check.
  -        full_check: If True, the function also checks for shapes that can be inferred.
  +        model: Model to check. If model is a path, the function checks model
  +            path first. If the model bytes size is larger than 2GB, function
  +            should be called using model path.
  +        full_check: If True, the function also runs shape inference check.
           skip_opset_compatibility_check: If True, the function skips the check for
               opset compatibility.
       """
  
verification_info: {"golden_diff": "diff --git a/onnx/checker.py b/onnx/checker.py\n--- a/onnx/checker.py\n+++ b/onnx/checker.py\n@@ -124,11 +124,20 @@\n     full_check: bool = False,\n     skip_opset_compatibility_check: bool = False,\n ) -> None:\n-    \"\"\"Check the consistency of a model. An exception is raised if the test fails.\n+    \"\"\"Check the consistency of a model.\n+\n+    An exception will be raised if the model's ir_version is not set\n+    properly or is higher than checker's ir_version, or if the model\n+    has duplicate keys in metadata_props.\n+\n+    If IR version >= 3, the model must specify opset_import.\n+    If IR version < 3, the model cannot have any opset_import specified.\n \n     Args:\n-        model: Model to check.\n-        full_check: If True, the function also checks for shapes that can be inferred.\n+        model: Model to check. If model is a path, the function checks model\n+            path first. If the model bytes size is larger than 2GB, function\n+            should be called using model path.\n+        full_check: If True, the function also runs shape inference check.\n         skip_opset_compatibility_check: If True, the function skips the check for\n             opset compatibility.\n     \"\"\"\n", "issue": "Refine docs for check_model\nCurrent version:\r\n\r\n> Check the consistency of a model. An exception is raised if the test fails.\r\n\r\nIt would be good if we document the kind of checks done and the type of exception raised so users know what to catch for; as well as clarify that it also runs shape inference when strict is True. (Right now it says `if True, the function checks shapes can be inferred`\uff09\r\n\r\nShould we default `strict` to `True`? @jcwchen \n", "before_files": [{"content": "# Copyright (c) ONNX Project Contributors\n#\n# SPDX-License-Identifier: Apache-2.0\n\"\"\"Graph utilities for checking whether an ONNX proto message is legal.\"\"\"\n\nfrom __future__ import annotations\n\n__all__ = [\n    \"check_attribute\",\n    \"check_function\",\n    \"check_graph\",\n    \"check_model\",\n    \"check_node\",\n    \"check_sparse_tensor\",\n    \"check_tensor\",\n    \"check_value_info\",\n    \"DEFAULT_CONTEXT\",\n    \"ValidationError\",\n    \"C\",\n    \"MAXIMUM_PROTOBUF\",\n]\n\nimport os\nimport sys\nfrom typing import Any, Callable, TypeVar\n\nfrom google.protobuf.message import Message\n\nimport onnx.defs\nimport onnx.onnx_cpp2py_export.checker as C  # noqa: N812\nimport onnx.shape_inference\nfrom onnx import (\n    IR_VERSION,\n    AttributeProto,\n    FunctionProto,\n    GraphProto,\n    ModelProto,\n    NodeProto,\n    SparseTensorProto,\n    TensorProto,\n    ValueInfoProto,\n    helper,\n)\n\n# Limitation of single protobuf file is 2GB\nMAXIMUM_PROTOBUF = 2000000000\n\n# TODO: This thing where we reserialize the protobuf back into the\n# string, only to deserialize it at the call site, is really goofy.\n# Stop doing that.\n\n\n# NB: Please don't edit this context!\nDEFAULT_CONTEXT = C.CheckerContext()\nDEFAULT_CONTEXT.ir_version = IR_VERSION\n# TODO: Maybe ONNX-ML should also be defaulted?\nDEFAULT_CONTEXT.opset_imports = {\"\": onnx.defs.onnx_opset_version()}\n\n\nFuncType = TypeVar(\"FuncType\", bound=Callable[..., Any])\n\n\ndef _ensure_proto_type(proto: Message, proto_type: type[Message]) -> None:\n    if not isinstance(proto, proto_type):\n        raise TypeError(\n            f\"The proto message needs to be of type '{proto_type.__name__}'\"\n        )\n\n\ndef check_value_info(\n    value_info: ValueInfoProto, ctx: C.CheckerContext = DEFAULT_CONTEXT\n) -> None:\n    _ensure_proto_type(value_info, ValueInfoProto)\n    return C.check_value_info(value_info.SerializeToString(), ctx)\n\n\ndef check_tensor(tensor: TensorProto, ctx: C.CheckerContext = DEFAULT_CONTEXT) -> None:\n    _ensure_proto_type(tensor, TensorProto)\n    return C.check_tensor(tensor.SerializeToString(), ctx)\n\n\ndef check_attribute(\n    attr: AttributeProto, ctx: C.CheckerContext = DEFAULT_CONTEXT\n) -> None:\n    _ensure_proto_type(attr, AttributeProto)\n    return C.check_attribute(attr.SerializeToString(), ctx)\n\n\ndef check_node(node: NodeProto, ctx: C.CheckerContext = DEFAULT_CONTEXT) -> None:\n    _ensure_proto_type(node, NodeProto)\n    return C.check_node(node.SerializeToString(), ctx)\n\n\ndef check_function(\n    function: FunctionProto, ctx: C.CheckerContext | None = None\n) -> None:\n    _ensure_proto_type(function, FunctionProto)\n    if ctx is None:\n        ctx = C.CheckerContext()\n        ctx.ir_version = helper.find_min_ir_version_for(\n            list(function.opset_import), True\n        )\n        function_opset_dic = {}\n        for domain_version in function.opset_import:\n            function_opset_dic[domain_version.domain] = domain_version.version\n        ctx.opset_imports = function_opset_dic\n    C.check_function(function.SerializeToString(), ctx)\n\n\ndef check_graph(graph: GraphProto, ctx: C.CheckerContext = DEFAULT_CONTEXT) -> None:\n    _ensure_proto_type(graph, GraphProto)\n    return C.check_graph(graph.SerializeToString(), ctx)\n\n\ndef check_sparse_tensor(\n    sparse: SparseTensorProto, ctx: C.CheckerContext = DEFAULT_CONTEXT\n) -> None:\n    _ensure_proto_type(sparse, SparseTensorProto)\n    C.check_sparse_tensor(sparse.SerializeToString(), ctx)\n\n\ndef check_model(\n    model: ModelProto | str | bytes | os.PathLike,\n    full_check: bool = False,\n    skip_opset_compatibility_check: bool = False,\n) -> None:\n    \"\"\"Check the consistency of a model. An exception is raised if the test fails.\n\n    Args:\n        model: Model to check.\n        full_check: If True, the function also checks for shapes that can be inferred.\n        skip_opset_compatibility_check: If True, the function skips the check for\n            opset compatibility.\n    \"\"\"\n    # If model is a path instead of ModelProto\n    if isinstance(model, (str, os.PathLike)):\n        C.check_model_path(os.fspath(model), full_check, skip_opset_compatibility_check)\n    else:\n        protobuf_string = (\n            model if isinstance(model, bytes) else model.SerializeToString()\n        )\n        # If the protobuf is larger than 2GB,\n        # remind users should use the model path to check\n        if sys.getsizeof(protobuf_string) > MAXIMUM_PROTOBUF:\n            raise ValueError(\n                \"This protobuf of onnx model is too large (>2GB). Call check_model with model path instead.\"\n            )\n        C.check_model(protobuf_string, full_check, skip_opset_compatibility_check)\n\n\nValidationError = C.ValidationError\n", "path": "onnx/checker.py"}], "after_files": [{"content": "# Copyright (c) ONNX Project Contributors\n#\n# SPDX-License-Identifier: Apache-2.0\n\"\"\"Graph utilities for checking whether an ONNX proto message is legal.\"\"\"\n\nfrom __future__ import annotations\n\n__all__ = [\n    \"check_attribute\",\n    \"check_function\",\n    \"check_graph\",\n    \"check_model\",\n    \"check_node\",\n    \"check_sparse_tensor\",\n    \"check_tensor\",\n    \"check_value_info\",\n    \"DEFAULT_CONTEXT\",\n    \"ValidationError\",\n    \"C\",\n    \"MAXIMUM_PROTOBUF\",\n]\n\nimport os\nimport sys\nfrom typing import Any, Callable, TypeVar\n\nfrom google.protobuf.message import Message\n\nimport onnx.defs\nimport onnx.onnx_cpp2py_export.checker as C  # noqa: N812\nimport onnx.shape_inference\nfrom onnx import (\n    IR_VERSION,\n    AttributeProto,\n    FunctionProto,\n    GraphProto,\n    ModelProto,\n    NodeProto,\n    SparseTensorProto,\n    TensorProto,\n    ValueInfoProto,\n    helper,\n)\n\n# Limitation of single protobuf file is 2GB\nMAXIMUM_PROTOBUF = 2000000000\n\n# TODO: This thing where we reserialize the protobuf back into the\n# string, only to deserialize it at the call site, is really goofy.\n# Stop doing that.\n\n\n# NB: Please don't edit this context!\nDEFAULT_CONTEXT = C.CheckerContext()\nDEFAULT_CONTEXT.ir_version = IR_VERSION\n# TODO: Maybe ONNX-ML should also be defaulted?\nDEFAULT_CONTEXT.opset_imports = {\"\": onnx.defs.onnx_opset_version()}\n\n\nFuncType = TypeVar(\"FuncType\", bound=Callable[..., Any])\n\n\ndef _ensure_proto_type(proto: Message, proto_type: type[Message]) -> None:\n    if not isinstance(proto, proto_type):\n        raise TypeError(\n            f\"The proto message needs to be of type '{proto_type.__name__}'\"\n        )\n\n\ndef check_value_info(\n    value_info: ValueInfoProto, ctx: C.CheckerContext = DEFAULT_CONTEXT\n) -> None:\n    _ensure_proto_type(value_info, ValueInfoProto)\n    return C.check_value_info(value_info.SerializeToString(), ctx)\n\n\ndef check_tensor(tensor: TensorProto, ctx: C.CheckerContext = DEFAULT_CONTEXT) -> None:\n    _ensure_proto_type(tensor, TensorProto)\n    return C.check_tensor(tensor.SerializeToString(), ctx)\n\n\ndef check_attribute(\n    attr: AttributeProto, ctx: C.CheckerContext = DEFAULT_CONTEXT\n) -> None:\n    _ensure_proto_type(attr, AttributeProto)\n    return C.check_attribute(attr.SerializeToString(), ctx)\n\n\ndef check_node(node: NodeProto, ctx: C.CheckerContext = DEFAULT_CONTEXT) -> None:\n    _ensure_proto_type(node, NodeProto)\n    return C.check_node(node.SerializeToString(), ctx)\n\n\ndef check_function(\n    function: FunctionProto, ctx: C.CheckerContext | None = None\n) -> None:\n    _ensure_proto_type(function, FunctionProto)\n    if ctx is None:\n        ctx = C.CheckerContext()\n        ctx.ir_version = helper.find_min_ir_version_for(\n            list(function.opset_import), True\n        )\n        function_opset_dic = {}\n        for domain_version in function.opset_import:\n            function_opset_dic[domain_version.domain] = domain_version.version\n        ctx.opset_imports = function_opset_dic\n    C.check_function(function.SerializeToString(), ctx)\n\n\ndef check_graph(graph: GraphProto, ctx: C.CheckerContext = DEFAULT_CONTEXT) -> None:\n    _ensure_proto_type(graph, GraphProto)\n    return C.check_graph(graph.SerializeToString(), ctx)\n\n\ndef check_sparse_tensor(\n    sparse: SparseTensorProto, ctx: C.CheckerContext = DEFAULT_CONTEXT\n) -> None:\n    _ensure_proto_type(sparse, SparseTensorProto)\n    C.check_sparse_tensor(sparse.SerializeToString(), ctx)\n\n\ndef check_model(\n    model: ModelProto | str | bytes | os.PathLike,\n    full_check: bool = False,\n    skip_opset_compatibility_check: bool = False,\n) -> None:\n    \"\"\"Check the consistency of a model.\n\n    An exception will be raised if the model's ir_version is not set\n    properly or is higher than checker's ir_version, or if the model\n    has duplicate keys in metadata_props.\n\n    If IR version >= 3, the model must specify opset_import.\n    If IR version < 3, the model cannot have any opset_import specified.\n\n    Args:\n        model: Model to check. If model is a path, the function checks model\n            path first. If the model bytes size is larger than 2GB, function\n            should be called using model path.\n        full_check: If True, the function also runs shape inference check.\n        skip_opset_compatibility_check: If True, the function skips the check for\n            opset compatibility.\n    \"\"\"\n    # If model is a path instead of ModelProto\n    if isinstance(model, (str, os.PathLike)):\n        C.check_model_path(os.fspath(model), full_check, skip_opset_compatibility_check)\n    else:\n        protobuf_string = (\n            model if isinstance(model, bytes) else model.SerializeToString()\n        )\n        # If the protobuf is larger than 2GB,\n        # remind users should use the model path to check\n        if sys.getsizeof(protobuf_string) > MAXIMUM_PROTOBUF:\n            raise ValueError(\n                \"This protobuf of onnx model is too large (>2GB). Call check_model with model path instead.\"\n            )\n        C.check_model(protobuf_string, full_check, skip_opset_compatibility_check)\n\n\nValidationError = C.ValidationError\n", "path": "onnx/checker.py"}]}