Add `device` argument to PyTorch Hub models
diff --git a/hubconf.py b/hubconf.py
index 3b3dfe0e9e2..f74e70c85a6 100644
--- a/hubconf.py
+++ b/hubconf.py
@@ -8,7 +8,7 @@
 import torch
 
 
-def _create(name, pretrained=True, channels=3, classes=80, autoshape=True, verbose=True):
+def _create(name, pretrained=True, channels=3, classes=80, autoshape=True, verbose=True, device=None):
     """Creates a specified YOLOv5 model
 
     Arguments:
@@ -18,6 +18,7 @@ def _create(name, pretrained=True, channels=3, classes=80, autoshape=True, verbo
         classes (int): number of model classes
         autoshape (bool): apply YOLOv5 .autoshape() wrapper to model
         verbose (bool): print all information to screen
+        device (str, torch.device, None): device to use for model parameters
 
     Returns:
         YOLOv5 pytorch model
@@ -50,7 +51,7 @@ def _create(name, pretrained=True, channels=3, classes=80, autoshape=True, verbo
                     model.names = ckpt['model'].names  # set class names attribute
         if autoshape:
             model = model.autoshape()  # for file/URI/PIL/cv2/np inputs and NMS
-        device = select_device('0' if torch.cuda.is_available() else 'cpu')  # default to GPU if available
+        device = select_device('0' if torch.cuda.is_available() else 'cpu') if device is None else torch.device(device)
         return model.to(device)
 
     except Exception as e:
@@ -59,49 +60,49 @@ def _create(name, pretrained=True, channels=3, classes=80, autoshape=True, verbo
         raise Exception(s) from e
 
 
-def custom(path='path/to/model.pt', autoshape=True, verbose=True):
+def custom(path='path/to/model.pt', autoshape=True, verbose=True, device=None):
     # YOLOv5 custom or local model
-    return _create(path, autoshape=autoshape, verbose=verbose)
+    return _create(path, autoshape=autoshape, verbose=verbose, device=device)
 
 
-def yolov5s(pretrained=True, channels=3, classes=80, autoshape=True, verbose=True):
+def yolov5s(pretrained=True, channels=3, classes=80, autoshape=True, verbose=True, device=None):
     # YOLOv5-small model https://github.com/ultralytics/yolov5
-    return _create('yolov5s', pretrained, channels, classes, autoshape, verbose)
+    return _create('yolov5s', pretrained, channels, classes, autoshape, verbose, device)
 
 
-def yolov5m(pretrained=True, channels=3, classes=80, autoshape=True, verbose=True):
+def yolov5m(pretrained=True, channels=3, classes=80, autoshape=True, verbose=True, device=None):
     # YOLOv5-medium model https://github.com/ultralytics/yolov5
-    return _create('yolov5m', pretrained, channels, classes, autoshape, verbose)
+    return _create('yolov5m', pretrained, channels, classes, autoshape, verbose, device)
 
 
-def yolov5l(pretrained=True, channels=3, classes=80, autoshape=True, verbose=True):
+def yolov5l(pretrained=True, channels=3, classes=80, autoshape=True, verbose=True, device=None):
     # YOLOv5-large model https://github.com/ultralytics/yolov5
-    return _create('yolov5l', pretrained, channels, classes, autoshape, verbose)
+    return _create('yolov5l', pretrained, channels, classes, autoshape, verbose, device)
 
 
-def yolov5x(pretrained=True, channels=3, classes=80, autoshape=True, verbose=True):
+def yolov5x(pretrained=True, channels=3, classes=80, autoshape=True, verbose=True, device=None):
     # YOLOv5-xlarge model https://github.com/ultralytics/yolov5
-    return _create('yolov5x', pretrained, channels, classes, autoshape, verbose)
+    return _create('yolov5x', pretrained, channels, classes, autoshape, verbose, device)
 
 
-def yolov5s6(pretrained=True, channels=3, classes=80, autoshape=True, verbose=True):
+def yolov5s6(pretrained=True, channels=3, classes=80, autoshape=True, verbose=True, device=None):
     # YOLOv5-small-P6 model https://github.com/ultralytics/yolov5
-    return _create('yolov5s6', pretrained, channels, classes, autoshape, verbose)
+    return _create('yolov5s6', pretrained, channels, classes, autoshape, verbose, device)
 
 
-def yolov5m6(pretrained=True, channels=3, classes=80, autoshape=True, verbose=True):
+def yolov5m6(pretrained=True, channels=3, classes=80, autoshape=True, verbose=True, device=None):
     # YOLOv5-medium-P6 model https://github.com/ultralytics/yolov5
-    return _create('yolov5m6', pretrained, channels, classes, autoshape, verbose)
+    return _create('yolov5m6', pretrained, channels, classes, autoshape, verbose, device)
 
 
-def yolov5l6(pretrained=True, channels=3, classes=80, autoshape=True, verbose=True):
+def yolov5l6(pretrained=True, channels=3, classes=80, autoshape=True, verbose=True, device=None):
     # YOLOv5-large-P6 model https://github.com/ultralytics/yolov5
-    return _create('yolov5l6', pretrained, channels, classes, autoshape, verbose)
+    return _create('yolov5l6', pretrained, channels, classes, autoshape, verbose, device)
 
 
-def yolov5x6(pretrained=True, channels=3, classes=80, autoshape=True, verbose=True):
+def yolov5x6(pretrained=True, channels=3, classes=80, autoshape=True, verbose=True, device=None):
     # YOLOv5-xlarge-P6 model https://github.com/ultralytics/yolov5
-    return _create('yolov5x6', pretrained, channels, classes, autoshape, verbose)
+    return _create('yolov5x6', pretrained, channels, classes, autoshape, verbose, device)
 
 
 if __name__ == '__main__':

For my usecase I would like to load the pretrained models from torchhub to cpu even if cuda is available. 

This merge request adds an optional parameter `device` to the `hubconf.py` functions to allow manual selection of target devices. 

## 🛠️ PR Summary

<sub>Made with ❤️ by [Ultralytics Actions](https://github.com/ultralytics/actions)<sub>

### 🌟 Summary
Added model device selection support to YOLOv5 model creation functions.

### 📊 Key Changes
- Introduced an additional `device` parameter to the `_create()` function and all model creator functions (e.g., `yolov5s`, `yolov5m`, etc.).
- The `device` parameter allows explicit selection of the computing device (CPU or GPU) where the model parameters will be loaded.

### 🎯 Purpose & Impact
- **Flexibility**: Users can now specify the device where they want to load the model, improving usability for systems with multiple GPUs or special hardware configurations.
- **Convenience**: This change makes it easier to deploy models in different environments (e.g., servers, laptops with or without GPU) by simplifying device management in code.
- **Control**: Advanced users gain finer control over resource allocation, which can improve performance and efficiency when running models.