Interpreter interface for TensorFlow Lite Models. This makes the TensorFlow Lite interpreter accessible in Python. It is possible to use this interpreter in a multithreaded Python environment, but you must be sure to call functions of a particular instance from only one thread at a time. So
| 171 | |
| 172 | @_tf_export('lite.Interpreter') |
| 173 | class Interpreter(object): |
| 174 | """Interpreter interface for TensorFlow Lite Models. |
| 175 | |
| 176 | This makes the TensorFlow Lite interpreter accessible in Python. |
| 177 | It is possible to use this interpreter in a multithreaded Python environment, |
| 178 | but you must be sure to call functions of a particular instance from only |
| 179 | one thread at a time. So if you want to have 4 threads running different |
| 180 | inferences simultaneously, create an interpreter for each one as thread-local |
| 181 | data. Similarly, if you are calling invoke() in one thread on a single |
| 182 | interpreter but you want to use tensor() on another thread once it is done, |
| 183 | you must use a synchronization primitive between the threads to ensure invoke |
| 184 | has returned before calling tensor(). |
| 185 | """ |
| 186 | |
| 187 | def __init__(self, |
| 188 | model_path=None, |
| 189 | model_content=None, |
| 190 | experimental_delegates=None): |
| 191 | """Constructor. |
| 192 | |
| 193 | Args: |
| 194 | model_path: Path to TF-Lite Flatbuffer file. |
| 195 | model_content: Content of model. |
| 196 | experimental_delegates: Experimental. Subject to change. List of |
| 197 | [TfLiteDelegate](https://www.tensorflow.org/lite/performance/delegates) |
| 198 | objects returned by lite.load_delegate(). |
| 199 | |
| 200 | Raises: |
| 201 | ValueError: If the interpreter was unable to create. |
| 202 | """ |
| 203 | if model_path and not model_content: |
| 204 | self._interpreter = ( |
| 205 | _interpreter_wrapper.InterpreterWrapper_CreateWrapperCPPFromFile( |
| 206 | model_path)) |
| 207 | if not self._interpreter: |
| 208 | raise ValueError('Failed to open {}'.format(model_path)) |
| 209 | elif model_content and not model_path: |
| 210 | # Take a reference, so the pointer remains valid. |
| 211 | # Since python strings are immutable then PyString_XX functions |
| 212 | # will always return the same pointer. |
| 213 | self._model_content = model_content |
| 214 | self._interpreter = ( |
| 215 | _interpreter_wrapper.InterpreterWrapper_CreateWrapperCPPFromBuffer( |
| 216 | model_content)) |
| 217 | elif not model_path and not model_path: |
| 218 | raise ValueError('`model_path` or `model_content` must be specified.') |
| 219 | else: |
| 220 | raise ValueError('Can\'t both provide `model_path` and `model_content`') |
| 221 | |
| 222 | # Each delegate is a wrapper that owns the delegates that have been loaded |
| 223 | # as plugins. The interpreter wrapper will be using them, but we need to |
| 224 | # hold them in a list so that the lifetime is preserved at least as long as |
| 225 | # the interpreter wrapper. |
| 226 | self._delegates = [] |
| 227 | if experimental_delegates: |
| 228 | self._delegates = experimental_delegates |
| 229 | for delegate in self._delegates: |
| 230 | self._interpreter.ModifyGraphWithDelegate( |
no outgoing calls