ruinmessi commited on
Commit
f3ca1f5
·
1 Parent(s): 774bd19

chore(core): update launch backend to subprocess (#158)

Browse files
tools/train.py CHANGED
@@ -12,7 +12,7 @@ import torch.backends.cudnn as cudnn
12
 
13
  from yolox.core import Trainer, launch
14
  from yolox.exp import get_exp
15
- from yolox.utils import configure_nccl
16
 
17
 
18
  def make_parser():
@@ -106,8 +106,8 @@ if __name__ == "__main__":
106
  exp = get_exp(args.exp_file, args.name)
107
  exp.merge(args.opts)
108
 
109
- num_gpu = torch.cuda.device_count() if args.devices is None else args.devices
110
- assert num_gpu <= torch.cuda.device_count()
111
 
112
  dist_url = "auto" if args.dist_url is None else args.dist_url
113
  launch(
 
12
 
13
  from yolox.core import Trainer, launch
14
  from yolox.exp import get_exp
15
+ from yolox.utils import configure_nccl, get_num_devices
16
 
17
 
18
  def make_parser():
 
106
  exp = get_exp(args.exp_file, args.name)
107
  exp.merge(args.opts)
108
 
109
+ num_gpu = get_num_devices() if args.devices is None else args.devices
110
+ assert num_gpu <= get_num_devices()
111
 
112
  dist_url = "auto" if args.dist_url is None else args.dist_url
113
  launch(
yolox/core/launch.py CHANGED
@@ -55,15 +55,17 @@ def launch(
55
  port = _find_free_port()
56
  dist_url = f"tcp://127.0.0.1:{port}"
57
 
58
- mp.spawn(
59
- _distributed_worker,
60
- nprocs=num_gpus_per_machine,
61
- args=(
62
- main_func, world_size, num_gpus_per_machine,
63
- machine_rank, backend, dist_url, args
64
- ),
65
- daemon=False,
66
- )
 
 
67
  else:
68
  main_func(*args)
69
 
 
55
  port = _find_free_port()
56
  dist_url = f"tcp://127.0.0.1:{port}"
57
 
58
+ processes = []
59
+ for rank in range(num_gpus_per_machine):
60
+ p = mp.Process(
61
+ target=_distributed_worker,
62
+ args=(
63
+ rank, main_func, world_size, num_gpus_per_machine,
64
+ machine_rank, backend, dist_url, args))
65
+ p.start()
66
+ processes.append(p)
67
+ for p in processes:
68
+ p.join()
69
  else:
70
  main_func(*args)
71
 
yolox/data/data_augment.py CHANGED
@@ -4,9 +4,6 @@
4
  """
5
  Data augmentation functionality. Passed as callable transformations to
6
  Dataset classes.
7
-
8
- The data augmentation procedures were interpreted from @weiliu89's SSD paper
9
- http://arxiv.org/abs/1512.02325
10
  """
11
 
12
  import math
@@ -17,6 +14,8 @@ import numpy as np
17
 
18
  import torch
19
 
 
 
20
 
21
  def augment_hsv(img, hgain=0.015, sgain=0.7, vgain=0.4):
22
  r = np.random.uniform(-1, 1, 3) * [hgain, sgain, vgain] + 1 # random gains
@@ -197,20 +196,11 @@ class TrainTransform:
197
  def __call__(self, image, targets, input_dim):
198
  boxes = targets[:, :4].copy()
199
  labels = targets[:, 4].copy()
200
- if targets.shape[1] > 5:
201
- mixup = True
202
- ratios = targets[:, -1].copy()
203
- ratios_o = targets[:, -1].copy()
204
- else:
205
- mixup = False
206
- ratios = None
207
- ratios_o = None
208
- lshape = 6 if mixup else 5
209
  if len(boxes) == 0:
210
- targets = np.zeros((self.max_labels, lshape), dtype=np.float32)
211
  image, r_o = preproc(image, input_dim, self.means, self.std)
212
  image = np.ascontiguousarray(image, dtype=np.float32)
213
- return image, targets
214
 
215
  image_o = image.copy()
216
  targets_o = targets.copy()
@@ -218,58 +208,36 @@ class TrainTransform:
218
  boxes_o = targets_o[:, :4]
219
  labels_o = targets_o[:, 4]
220
  # bbox_o: [xyxy] to [c_x,c_y,w,h]
221
- b_x_o = (boxes_o[:, 2] + boxes_o[:, 0]) * 0.5
222
- b_y_o = (boxes_o[:, 3] + boxes_o[:, 1]) * 0.5
223
- b_w_o = (boxes_o[:, 2] - boxes_o[:, 0]) * 1.0
224
- b_h_o = (boxes_o[:, 3] - boxes_o[:, 1]) * 1.0
225
- boxes_o[:, 0] = b_x_o
226
- boxes_o[:, 1] = b_y_o
227
- boxes_o[:, 2] = b_w_o
228
- boxes_o[:, 3] = b_h_o
229
 
230
  image_t = _distort(image)
231
  image_t, boxes = _mirror(image_t, boxes)
232
  height, width, _ = image_t.shape
233
  image_t, r_ = preproc(image_t, input_dim, self.means, self.std)
234
- boxes = boxes.copy()
235
  # boxes [xyxy] 2 [cx,cy,w,h]
236
- b_x = (boxes[:, 2] + boxes[:, 0]) * 0.5
237
- b_y = (boxes[:, 3] + boxes[:, 1]) * 0.5
238
- b_w = (boxes[:, 2] - boxes[:, 0]) * 1.0
239
- b_h = (boxes[:, 3] - boxes[:, 1]) * 1.0
240
- boxes[:, 0] = b_x
241
- boxes[:, 1] = b_y
242
- boxes[:, 2] = b_w
243
- boxes[:, 3] = b_h
244
 
245
  boxes *= r_
246
 
247
  mask_b = np.minimum(boxes[:, 2], boxes[:, 3]) > 8
248
  boxes_t = boxes[mask_b]
249
- labels_t = labels[mask_b].copy()
250
- if mixup:
251
- ratios_t = ratios[mask_b].copy()
252
 
253
  if len(boxes_t) == 0:
254
  image_t, r_o = preproc(image_o, input_dim, self.means, self.std)
255
  boxes_o *= r_o
256
  boxes_t = boxes_o
257
  labels_t = labels_o
258
- ratios_t = ratios_o
259
 
260
  labels_t = np.expand_dims(labels_t, 1)
261
- if mixup:
262
- ratios_t = np.expand_dims(ratios_t, 1)
263
- targets_t = np.hstack((labels_t, boxes_t, ratios_t))
264
- else:
265
- targets_t = np.hstack((labels_t, boxes_t))
266
- padded_labels = np.zeros((self.max_labels, lshape))
267
  padded_labels[range(len(targets_t))[: self.max_labels]] = targets_t[
268
  : self.max_labels
269
  ]
270
  padded_labels = np.ascontiguousarray(padded_labels, dtype=np.float32)
271
  image_t = np.ascontiguousarray(image_t, dtype=np.float32)
272
- return image_t, padded_labels
273
 
274
 
275
  class ValTransform:
@@ -298,4 +266,4 @@ class ValTransform:
298
  # assume input is cv2 img for now
299
  def __call__(self, img, res, input_size):
300
  img, _ = preproc(img, input_size, self.means, self.std, self.swap)
301
- return torch.from_numpy(img), torch.zeros(1, 5)
 
4
  """
5
  Data augmentation functionality. Passed as callable transformations to
6
  Dataset classes.
 
 
 
7
  """
8
 
9
  import math
 
14
 
15
  import torch
16
 
17
+ from yolox.utils import xyxy2cxcywh
18
+
19
 
20
  def augment_hsv(img, hgain=0.015, sgain=0.7, vgain=0.4):
21
  r = np.random.uniform(-1, 1, 3) * [hgain, sgain, vgain] + 1 # random gains
 
196
  def __call__(self, image, targets, input_dim):
197
  boxes = targets[:, :4].copy()
198
  labels = targets[:, 4].copy()
 
 
 
 
 
 
 
 
 
199
  if len(boxes) == 0:
200
+ targets = np.zeros((self.max_labels, 5), dtype=np.float32)
201
  image, r_o = preproc(image, input_dim, self.means, self.std)
202
  image = np.ascontiguousarray(image, dtype=np.float32)
203
+ return torch.as_tensor(image), torch.as_tensor(targets)
204
 
205
  image_o = image.copy()
206
  targets_o = targets.copy()
 
208
  boxes_o = targets_o[:, :4]
209
  labels_o = targets_o[:, 4]
210
  # bbox_o: [xyxy] to [c_x,c_y,w,h]
211
+ boxes_o = xyxy2cxcywh(boxes_o)
 
 
 
 
 
 
 
212
 
213
  image_t = _distort(image)
214
  image_t, boxes = _mirror(image_t, boxes)
215
  height, width, _ = image_t.shape
216
  image_t, r_ = preproc(image_t, input_dim, self.means, self.std)
217
+ boxes = xyxy2cxcywh(boxes)
218
  # boxes [xyxy] 2 [cx,cy,w,h]
 
 
 
 
 
 
 
 
219
 
220
  boxes *= r_
221
 
222
  mask_b = np.minimum(boxes[:, 2], boxes[:, 3]) > 8
223
  boxes_t = boxes[mask_b]
224
+ labels_t = labels[mask_b]
 
 
225
 
226
  if len(boxes_t) == 0:
227
  image_t, r_o = preproc(image_o, input_dim, self.means, self.std)
228
  boxes_o *= r_o
229
  boxes_t = boxes_o
230
  labels_t = labels_o
 
231
 
232
  labels_t = np.expand_dims(labels_t, 1)
233
+ targets_t = np.hstack((labels_t, boxes_t))
234
+ padded_labels = np.zeros((self.max_labels, 5))
 
 
 
 
235
  padded_labels[range(len(targets_t))[: self.max_labels]] = targets_t[
236
  : self.max_labels
237
  ]
238
  padded_labels = np.ascontiguousarray(padded_labels, dtype=np.float32)
239
  image_t = np.ascontiguousarray(image_t, dtype=np.float32)
240
+ return torch.as_tensor(image_t), torch.as_tensor(padded_labels)
241
 
242
 
243
  class ValTransform:
 
266
  # assume input is cv2 img for now
267
  def __call__(self, img, res, input_size):
268
  img, _ = preproc(img, input_size, self.means, self.std, self.swap)
269
+ return torch.tensor_as(img), torch.zeros(1, 5)
yolox/data/datasets/mosaicdetection.py CHANGED
@@ -220,4 +220,4 @@ class MosaicDetection(Dataset):
220
  origin_img = origin_img.astype(np.float32)
221
  origin_img = 0.5 * origin_img + 0.5 * padded_cropped_img.astype(np.float32)
222
 
223
- return origin_img.astype(np.uint8), origin_labels
 
220
  origin_img = origin_img.astype(np.float32)
221
  origin_img = 0.5 * origin_img + 0.5 * padded_cropped_img.astype(np.float32)
222
 
223
+ return origin_img, origin_labels
yolox/utils/boxes.py CHANGED
@@ -9,7 +9,7 @@ import torchvision
9
 
10
  __all__ = [
11
  "filter_box", "postprocess", "bboxes_iou", "matrix_iou",
12
- "adjust_box_anns", "xyxy2xywh",
13
  ]
14
 
15
 
@@ -113,3 +113,11 @@ def xyxy2xywh(bboxes):
113
  bboxes[:, 2] = bboxes[:, 2] - bboxes[:, 0]
114
  bboxes[:, 3] = bboxes[:, 3] - bboxes[:, 1]
115
  return bboxes
 
 
 
 
 
 
 
 
 
9
 
10
  __all__ = [
11
  "filter_box", "postprocess", "bboxes_iou", "matrix_iou",
12
+ "adjust_box_anns", "xyxy2xywh", "xyxy2cxcywh",
13
  ]
14
 
15
 
 
113
  bboxes[:, 2] = bboxes[:, 2] - bboxes[:, 0]
114
  bboxes[:, 3] = bboxes[:, 3] - bboxes[:, 1]
115
  return bboxes
116
+
117
+
118
+ def xyxy2cxcywh(bboxes):
119
+ bboxes[:, 2] = bboxes[:, 2] - bboxes[:, 0]
120
+ bboxes[:, 3] = bboxes[:, 3] - bboxes[:, 1]
121
+ bboxes[:, 0] = bboxes[:, 0] + bboxes[:, 2] * 0.5
122
+ bboxes[:, 1] = bboxes[:, 1] + bboxes[:, 3] * 0.5
123
+ return bboxes
yolox/utils/metric.py CHANGED
@@ -13,12 +13,19 @@ import torch
13
  __all__ = [
14
  "AverageMeter",
15
  "MeterBuffer",
 
16
  "get_total_and_free_memory_in_Mb",
17
  "occupy_mem",
18
  "gpu_mem_usage",
19
  ]
20
 
21
 
 
 
 
 
 
 
22
  def get_total_and_free_memory_in_Mb(cuda_device):
23
  devices_info_str = os.popen(
24
  "nvidia-smi --query-gpu=memory.total,memory.used --format=csv,nounits,noheader"
 
13
  __all__ = [
14
  "AverageMeter",
15
  "MeterBuffer",
16
+ "get_num_devices",
17
  "get_total_and_free_memory_in_Mb",
18
  "occupy_mem",
19
  "gpu_mem_usage",
20
  ]
21
 
22
 
23
+ def get_num_devices():
24
+ devices_list_info = os.popen("nvidia-smi -L")
25
+ devices_list_info = devices_list_info.read().strip().split("\n")
26
+ return len(devices_list_info)
27
+
28
+
29
  def get_total_and_free_memory_in_Mb(cuda_device):
30
  devices_info_str = os.popen(
31
  "nvidia-smi --query-gpu=memory.total,memory.used --format=csv,nounits,noheader"
yolox/utils/setup_env.py CHANGED
@@ -48,3 +48,5 @@ def configure_module(ulimit_value=8192):
48
  except Exception:
49
  # cv2 version mismatch might rasie exceptions.
50
  pass
 
 
 
48
  except Exception:
49
  # cv2 version mismatch might rasie exceptions.
50
  pass
51
+
52
+ os.environ["OMP_NUM_THREADS"] = str(1)