|
1 |
| -from functools import wraps, partial |
2 |
| -from typing import Union, AnyStr, ByteString, List, Sequence, Any |
3 | 1 | import warnings
|
| 2 | +from functools import partial, wraps |
| 3 | +from typing import Any, AnyStr, ByteString, List, Sequence, Union |
4 | 4 |
|
5 |
| -from redis import StrictRedis |
6 | 5 | import numpy as np
|
| 6 | +from deprecated import deprecated |
| 7 | +from redis import StrictRedis |
7 | 8 |
|
8 | 9 | from redisai import command_builder as builder
|
9 | 10 | from redisai.dag import Dag
|
10 | 11 | from redisai.pipeline import Pipeline
|
11 | 12 | from redisai.postprocessor import Processor
|
12 | 13 |
|
13 |
| - |
14 | 14 | processor = Processor()
|
15 | 15 |
|
16 | 16 |
|
@@ -96,7 +96,7 @@ def dag(
|
96 | 96 | -------
|
97 | 97 | >>> con.tensorset('tensor', ...)
|
98 | 98 | 'OK'
|
99 |
| - >>> con.modelset('model', ...) |
| 99 | + >>> con.modelstore('model', ...) |
100 | 100 | 'OK'
|
101 | 101 | >>> dag = con.dag(load=['tensor'], persist=['output'])
|
102 | 102 | >>> dag.tensorset('another', ...)
|
@@ -136,6 +136,83 @@ def loadbackend(self, identifier: AnyStr, path: AnyStr) -> str:
|
136 | 136 | res = self.execute_command(*args)
|
137 | 137 | return res if not self.enable_postprocess else processor.loadbackend(res)
|
138 | 138 |
|
| 139 | + def modelstore( |
| 140 | + self, |
| 141 | + key: AnyStr, |
| 142 | + backend: str, |
| 143 | + device: str, |
| 144 | + data: ByteString, |
| 145 | + batch: int = None, |
| 146 | + minbatch: int = None, |
| 147 | + minbatchtimeout: int = None, |
| 148 | + tag: AnyStr = None, |
| 149 | + inputs: Union[AnyStr, List[AnyStr]] = None, |
| 150 | + outputs: Union[AnyStr, List[AnyStr]] = None, |
| 151 | + ) -> str: |
| 152 | + """ |
| 153 | + Set the model on provided key. |
| 154 | +
|
| 155 | + Parameters |
| 156 | + ---------- |
| 157 | + key : AnyStr |
| 158 | + Key name |
| 159 | + backend : str |
| 160 | + Backend name. Allowed backends are TF, TORCH, TFLITE, ONNX |
| 161 | + device : str |
| 162 | + Device name. Allowed devices are CPU and GPU. If multiple GPUs are available, |
| 163 | + it can be specified using the format GPU:<gpu number>. For example: GPU:0 |
| 164 | + data : bytes |
| 165 | + Model graph read as bytes string |
| 166 | + batch : int |
| 167 | + Number of batches for doing auto-batching |
| 168 | + minbatch : int |
| 169 | + Minimum number of samples required in a batch for model execution |
| 170 | + minbatchtimeout : int |
| 171 | + The max number of miliseconds for which the engine will not trigger an execution |
| 172 | + if the number of samples is lower than minbatch (after minbatchtimeout is passed, |
| 173 | + the execution will start even if minbatch jas not reached) |
| 174 | + tag : AnyStr |
| 175 | + Any string that will be saved in RedisAI as tag for the model |
| 176 | + inputs : Union[AnyStr, List[AnyStr]] |
| 177 | + Input node(s) in the graph. Required only Tensorflow graphs |
| 178 | + outputs : Union[AnyStr, List[AnyStr]] |
| 179 | + Output node(s) in the graph Required only for Tensorflow graphs |
| 180 | +
|
| 181 | + Returns |
| 182 | + ------- |
| 183 | + str |
| 184 | + 'OK' if success, raise an exception otherwise |
| 185 | +
|
| 186 | + Example |
| 187 | + ------- |
| 188 | + >>> # Torch model |
| 189 | + >>> model_path = os.path.join('path/to/TorchScriptModel.pt') |
| 190 | + >>> model = open(model_path, 'rb').read() |
| 191 | + >>> con.modeltore("model", 'torch', 'cpu', model, tag='v1.0') |
| 192 | + 'OK' |
| 193 | + >>> # Tensorflow model |
| 194 | + >>> model_path = os.path.join('/path/to/tf_frozen_graph.pb') |
| 195 | + >>> model = open(model_path, 'rb').read() |
| 196 | + >>> con.modelstore('m', 'tf', 'cpu', model, |
| 197 | + ... inputs=['a', 'b'], outputs=['mul'], tag='v1.0') |
| 198 | + 'OK' |
| 199 | + """ |
| 200 | + args = builder.modelstore( |
| 201 | + key, |
| 202 | + backend, |
| 203 | + device, |
| 204 | + data, |
| 205 | + batch, |
| 206 | + minbatch, |
| 207 | + minbatchtimeout, |
| 208 | + tag, |
| 209 | + inputs, |
| 210 | + outputs, |
| 211 | + ) |
| 212 | + res = self.execute_command(*args) |
| 213 | + return res if not self.enable_postprocess else processor.modelstore(res) |
| 214 | + |
| 215 | + @deprecated(version="1.2.0", reason="Use modelstore instead") |
139 | 216 | def modelset(
|
140 | 217 | self,
|
141 | 218 | key: AnyStr,
|
@@ -247,6 +324,56 @@ def modeldel(self, key: AnyStr) -> str:
|
247 | 324 | res = self.execute_command(*args)
|
248 | 325 | return res if not self.enable_postprocess else processor.modeldel(res)
|
249 | 326 |
|
| 327 | + def modelexecute( |
| 328 | + self, |
| 329 | + key: AnyStr, |
| 330 | + inputs: Union[AnyStr, List[AnyStr]], |
| 331 | + outputs: Union[AnyStr, List[AnyStr]], |
| 332 | + timeout: int = None, |
| 333 | + ) -> str: |
| 334 | + """ |
| 335 | + Run the model using input(s) which are already in the scope and are associated |
| 336 | + to some keys. Modelexecute also needs the output key name(s) to store the output |
| 337 | + from the model. The number of outputs from the model and the number of keys |
| 338 | + provided here must be same. Otherwise, RedisAI throws an error |
| 339 | +
|
| 340 | + Parameters |
| 341 | + ---------- |
| 342 | + key : str |
| 343 | + Model key to run |
| 344 | + inputs : Union[AnyStr, List[AnyStr]] |
| 345 | + Tensor(s) which is already saved in the RedisAI using a tensorset call. These |
| 346 | + tensors will be used as the inputs for the modelexecute |
| 347 | + outputs : Union[AnyStr, List[AnyStr]] |
| 348 | + keys on which the outputs to be saved. If those keys exist already, |
| 349 | + modelexecute will overwrite them with new values |
| 350 | + timeout : int |
| 351 | + The max number on milisecinds that may pass before the request is prossced |
| 352 | + (meaning that the result will not be computed after that time and TIMEDOUT |
| 353 | + is returned in that case |
| 354 | +
|
| 355 | + Returns |
| 356 | + ------- |
| 357 | + str |
| 358 | + 'OK' if success, raise an exception otherwise |
| 359 | +
|
| 360 | + Example |
| 361 | + ------- |
| 362 | + >>> con.modelstore('m', 'tf', 'cpu', model_pb, |
| 363 | + ... inputs=['a', 'b'], outputs=['mul'], tag='v1.0') |
| 364 | + 'OK' |
| 365 | + >>> con.tensorset('a', (2, 3), dtype='float') |
| 366 | + 'OK' |
| 367 | + >>> con.tensorset('b', (2, 3), dtype='float') |
| 368 | + 'OK' |
| 369 | + >>> con.modelexecute('m', ['a', 'b'], ['c']) |
| 370 | + 'OK' |
| 371 | + """ |
| 372 | + args = builder.modelexecute(key, inputs, outputs, timeout) |
| 373 | + res = self.execute_command(*args) |
| 374 | + return res if not self.enable_postprocess else processor.modelexecute(res) |
| 375 | + |
| 376 | + @deprecated(version="1.2.0", reason="Use modelexecute instead") |
250 | 377 | def modelrun(
|
251 | 378 | self,
|
252 | 379 | key: AnyStr,
|
@@ -277,7 +404,7 @@ def modelrun(
|
277 | 404 |
|
278 | 405 | Example
|
279 | 406 | -------
|
280 |
| - >>> con.modelset('m', 'tf', 'cpu', model_pb, |
| 407 | + >>> con.modelstore('m', 'tf', 'cpu', model_pb, |
281 | 408 | ... inputs=['a', 'b'], outputs=['mul'], tag='v1.0')
|
282 | 409 | 'OK'
|
283 | 410 | >>> con.tensorset('a', (2, 3), dtype='float')
|
|
0 commit comments