Comments (3)
Hello @Edwardmark !
Because of the dynamic batching, Triton assumes, that all samples within a batch have the same shape. Therefore, if Triton receives two infer requests: [1, 640, 480, 3]
and [2, 640, 480, 3]
, it will batch them together into [3, 640, 480, 3]
.
To work this around, I suggest one of the following approaches:
- Just send the different sized images in different batches. Ofc, this will only work if you expect to have similar sizes of images.
- The easy situation is when you are using
fn.decoders.image
inside DALI's pipeline, i.e. you are sending encoded images to DALI Backend. Then all you need to do (in the triton client) is to pad all encoded buffers with zeros (every decoder will just discard them), something like:
def array_from_list(arrays):
"""
Convert list of ndarrays to single ndarray with ndims+=1
:param arrays List of ndarrays
"""
lengths = list(map(lambda x, arr=arrays: arr[x].shape[0], [x for x in range(len(arrays))]))
max_len = max(lengths)
arrays = list(map(lambda arr, ml=max_len: np.pad(arr, ((0, ml - arr.shape[0]))), arrays))
for arr in arrays: # Sanity check
assert arr.shape == arrays[0].shape, "Arrays must have the same shape"
return np.stack(arrays)
- If you need to input decoded images, things will get hacky:
- First of all, in the Client you need to read the actual sizes of images and then pad them (with any value)
- Create an extra input (
fn.external_source
) in DALI pipeline, which will get the shape of every image before padding - Use
fn.crop
operator to crop the images within DALI pipeline
# Client code
def batch_from_list(images):
"""
:param images: List of images
:return: Tuple: (Padded images, image shapes before padding)
"""
...
return batch, shapes
# DALI pipeline code
@dali.pipeline_def(batch_size=32, num_threads=8, device_id=0)
def pipe():
images = fn.external_source(name="IMAGE_ARRAY")
shapes = fn.external_source(name="SHAPES", device="cpu") # Note the device="cpu", this is necessary
images = fn.crop(images, crop=shapes, ...)
...
return images
Should you have any more questions, don't hesitate to ask.
from dali_backend.
@szalpal ,hi, I try to inference with encoded images, and save the decoded ones to output, but the result is not true, when different shape image is feed to pipeline.
The config.pbtxt is as follows:
# https://github.com/triton-inference-server/dali_backend/issues/18
name: "dali_det_pre"
backend: "dali"
max_batch_size: 32
input [
{
name: "IMAGE_RAW"
data_type: TYPE_UINT8
dims: [ -1 ]
}
]
output [
{
name: "DALI_OUTPUT_0" # original image
data_type: TYPE_UINT8
dims: [-1, -1, 3]
},
{
name: "DALI_OUTPUT_1" # resized image
data_type: TYPE_FP32
dims: [3, 640, 640]
},
{
name: "DALI_OUTPUT_2" # ratio
data_type: TYPE_FP32
dims: [2]
}
]
dynamic_batching {
preferred_batch_size: [ 4, 8, 16, 32 ]
max_queue_delay_microseconds: 100
}
The dali pipeline is as follows:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import nvidia.dali as dali
import nvidia.dali.fn as fn
import nvidia.dali.types as types
import argparse
import numpy as np
import os
pipe = dali.pipeline.Pipeline(batch_size=32, num_threads=8)
with pipe:
expect_output_size = (640., 640.)
images_raw = fn.external_source(device='cpu', name="IMAGE_RAW")
images = fn.image_decoder(images_raw, device="mixed", output_type=types.RGB)
raw_shapes = fn.shapes(images, dtype=types.INT32)
norm_images = fn.resize(
images,
mode='not_larger',
size=expect_output_size,
)
resized_shapes = fn.shapes(norm_images, dtype=types.INT32)
ratio = fn.slice(resized_shapes / raw_shapes, 0, 2, axes=[0])
norm_images = fn.crop_mirror_normalize(norm_images, mean=[0.], std=[255.], output_layout='CHW')
norm_images = fn.pad(norm_images, axis_names="HW", align=expect_output_size)
pipe.set_outputs(images, norm_images, ratio)
pipe.serialize(filename="1/model.dali")
The client is as follows:
image_data, im_paths = load_images(FLAGS.img_dir if FLAGS.img_dir is not None else FLAGS.img,
max_images=FLAGS.batch_size * FLAGS.n_iter)
image_data = array_from_list(image_data)
print("Images loaded")
inputs = generate_inputs(FLAGS.input_name, image_data.shape, "UINT8")
outputs = generate_outputs(FLAGS.output_names)
# Initialize the data
inputs[0].set_data_from_numpy(image_data)
# Test with outputs
results = triton_client.infer(model_name=model_name, inputs=inputs, outputs=outputs)
#import pdb;pdb.set_trace()
org_im = results.as_numpy(FLAGS.output_names[0])
but the result is strage,
with shape as (5, 2521, 3361, 3), so how to recover the real orginal image?
from dali_backend.
I don't fully understand, what would you like to achieve. Could you describe, what would you like for the DALI pipeline to do? This way we can verify, if DALI pipeline if written correctly
from dali_backend.
Related Issues (20)
- Batching does not improve performance with dali HOT 10
- Can dali backend support default values or optional input? HOT 2
- Unexpected large memory needed for gpu resize HOT 4
- Error in thread 31: nvJPEG error (5): The user-provided allocator functions, for either memory allocation or for releasing the memory, returned a non-zero code. HOT 6
- Cannot compile dali_backend with older version of triton HOT 2
- how to provide batch input data for dali pipeline whicn input shapes [-1] HOT 1
- if I want to crop from different start point, how can I build pipe to do this? HOT 2
- Test issue
- Connecting InputOperator with no explicit inputs to Triton HOT 12
- Could not serialize dali.fn.python_function HOT 1
- when using crop_mirror_normalize func, Output layout "CHW" is slower than "HWC" HOT 5
- dlopen libcuda.so failed!. Please install GPU dirverTraceback (most recent call last): HOT 4
- Prefeed multiple input batches to the inference pipeline HOT 7
- Unable to load numpy module in a DALI backend HOT 3
- DALI pipeline in Triton - formatting InferInput batch of images for UINT8 HOT 3
- 'NoneType' object has no attribute 'loader' when trying to load DALI model. HOT 15
- How to format client code for inception example HOT 14
- How to get list of image paths into dali pipeline? HOT 4
- How to use scalar inputs HOT 3
- Video Input larger than max
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dali_backend.