microsoft / onnxruntime-inference-examples

Examples for using ONNX Runtime for machine learning inferencing.
MIT License
1.15k stars 324 forks source link

Using the yolov3 get_prediction_evaluation_yolov3_variant throws an exception. #248

Open berserkr opened 1 year ago

berserkr commented 1 year ago

Finding optimal threshold for each tensor using entropy algorithm ... Number of tensors : 397 Number of histogram bins : 128 (The number may increase depends on the data it collects) Number of quantized bins : 128 Traceback (most recent call last): File "e2e_user_yolov3_example.py", line 241, in get_calibration_table_tofa(model_path, augmented_model_path, calibration_dataset) File "e2e_user_yolov3_example.py", line 175, in get_prediction_evaluation_yolov3_variant write_calibration_table(calibrator.compute_range()) File "/home/lbathen/miniconda3/envs/onnx/lib/python3.8/site-packages/onnxruntime/quantization/quant_utils.py", line 409, in write_calibration_table file.write(json.dumps(calibration_cache)) # use json.loads to do the reverse File "/home/lbathen/miniconda3/envs/onnx/lib/python3.8/json/init.py", line 231, in dumps return _default_encoder.encode(obj) File "/home/lbathen/miniconda3/envs/onnx/lib/python3.8/json/encoder.py", line 199, in encode chunks = self.iterencode(o, _one_shot=True) File "/home/lbathen/miniconda3/envs/onnx/lib/python3.8/json/encoder.py", line 257, in iterencode return _iterencode(o, 0) File "/home/lbathen/miniconda3/envs/onnx/lib/python3.8/json/encoder.py", line 179, in default raise TypeError(f'Object of type {o.class.name} ' TypeError: Object of type float32 is not JSON serializable

--- To reproduce, download and use a different variant of Yolo, and use the get_prediction_evaluation_yolov3_variant method...

onnx==1.14.0 onnxruntime-gpu==1.14.1 cuda 12.1 ubuntu 20.04

---- Reproducible on two separate machines... ubuntu 20 and 22...

berserkr commented 1 year ago

A follow up. It seems that when the calibration_cache gets to the line where json is supposed to write it down, it somehow is unable to recognize that the range is a tuple... could be some type of encoding issue... The hack to get it to work is by extracting the tuple, converting the values to floats, and then re-assigning the tuple.... it then is able to proceed...

edgchen1 commented 1 year ago

assuming this is referring to https://github.com/microsoft/onnxruntime-inference-examples/blob/main/quantization/object_detection/trt/yolov3/e2e_user_yolov3_example.py

@yufenglee mind taking a look?

fangpings commented 1 year ago

Also encountered this problem when running a modified version of Bert quantization example

Traceback (most recent call last):
  File "/mnt/task_runtime/finetune/quantization.py", line 118, in <module>
    write_calibration_table(compute_range)
  File "/opt/python/lib/python3.9/site-packages/onnxruntime/quantization/quant_utils.py", line 407, in write_calibration_table
    file.write(json.dumps(calibration_cache))  # use `json.loads` to do the reverse
  File "/opt/python/lib/python3.9/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/opt/python/lib/python3.9/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/opt/python/lib/python3.9/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/opt/python/lib/python3.9/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
fangpings commented 1 year ago

A follow up. It seems that when the calibration_cache gets to the line where json is supposed to write it down, it somehow is unable to recognize that the range is a tuple... could be some type of encoding issue... The hack to get it to work is by extracting the tuple, converting the values to floats, and then re-assigning the tuple.... it then is able to proceed...

Hi @bererkr mind sharing some more details about this? Trying to hack this :(

yufenglee commented 1 year ago

@chilo-ms, could you please help take a look?

fangpings commented 1 year ago

Update, this solves the problem

  compute_range = calibrator.compute_range()
  # there is a bug in conversion, see this issue
  new_compute_range = {}
  for k, v in compute_range.items():
      v1, v2 = v
      new_compute_range[k] = (float(v1), float(v2))
  write_calibration_table(new_compute_range)