Repository: ultralytics/ultralytics
Issue category: Bug Report

Issue:
Saving yolov6n crashes
### Search before asking

- [X] I have searched the Ultralytics YOLO [issues](https://github.com/ultralytics/ultralytics/issues) and found no similar bug report.


### Ultralytics YOLO Component

Export

### Bug

Crash on "yolov6n.yaml" save.

```
New https://pypi.org/project/ultralytics/8.3.49 available 😃 Update with 'pip install -U ultralytics'
Ultralytics 8.3.44 🚀 Python-3.10.12 torch-2.5.1+cu124 CPU (AMD Ryzen 3 3200G with Radeon Vega Graphics)
engine/trainer: task=detect, mode=train, model=yolov6n.yaml, data=coco8.yaml, epochs=1, time=None, patience=100, batch=16, imgsz=640, save=True, save_period=-1, cache=False, device=None, workers=8, project=None, name=train11, exist_ok=False, pretrained=True, optimizer=auto, verbose=True, seed=0, deterministic=True, single_cls=False, rect=False, cos_lr=False, close_mosaic=10, resume=False, amp=True, fraction=1.0, profile=False, freeze=None, multi_scale=False, overlap_mask=True, mask_ratio=4, dropout=0.0, val=True, split=val, save_json=False, save_hybrid=False, conf=None, iou=0.7, max_det=300, half=False, dnn=False, plots=True, source=None, vid_stride=1, stream_buffer=False, visualize=False, augment=False, agnostic_nms=False, classes=None, retina_masks=False, embed=None, show=False, save_frames=False, save_txt=False, save_conf=False, save_crop=False, show_labels=True, show_conf=True, show_boxes=True, line_width=None, format=torchscript, keras=False, optimize=False, int8=False, dynamic=False, simplify=True, opset=None, workspace=None, nms=False, lr0=0.01, lrf=0.01, momentum=0.937, weight_decay=0.0005, warmup_epochs=3.0, warmup_momentum=0.8, warmup_bias_lr=0.1, box=7.5, cls=0.5, dfl=1.5, pose=12.0, kobj=1.0, nbs=64, hsv_h=0.015, hsv_s=0.7, hsv_v=0.4, degrees=0.0, translate=0.1, scale=0.5, shear=0.0, perspective=0.0, flipud=0.0, fliplr=0.5, bgr=0.0, mosaic=1.0, mixup=0.0, copy_paste=0.0, copy_paste_mode=flip, auto_augment=randaugment, erasing=0.4, crop_fraction=1.0, cfg=None, tracker=botsort.yaml, save_dir=runs/detect/train11
activation: nn.ReLU()

                   from  n    params  module                                       arguments                     
  0                  -1  1       464  ultralytics.nn.modules.conv.Conv             [3, 16, 3, 2]                 
  1                  -1  1      4672  ultralytics.nn.modules.conv.Conv             [16, 32, 3, 2]                
  2                  -1  2     18560  ultralytics.nn.modules.conv.Conv             [32, 32, 3, 1]                
  3                  -1  1     18560  ultralytics.nn.modules.conv.Conv             [32, 64, 3, 2]                
  4                  -1  4    147968  ultralytics.nn.modules.conv.Conv             [64, 64, 3, 1]                
  5                  -1  1     73984  ultralytics.nn.modules.conv.Conv             [64, 128, 3, 2]               
  6                  -1  6    886272  ultralytics.nn.modules.conv.Conv             [128, 128, 3, 1]              
  7                  -1  1    295424  ultralytics.nn.modules.conv.Conv             [128, 256, 3, 2]              
  8                  -1  2   1180672  ultralytics.nn.modules.conv.Conv             [256, 256, 3, 1]              
  9                  -1  1    164608  ultralytics.nn.modules.block.SPPF            [256, 256, 5]                 
 10                  -1  1     16512  ultralytics.nn.modules.conv.Conv             [256, 64, 1, 1]               
 11                  -1  1     16448  torch.nn.modules.conv.ConvTranspose2d        [64, 64, 2, 2, 0]             
 12             [-1, 6]  1         0  ultralytics.nn.modules.conv.Concat           [1]                           
 13                  -1  1    110720  ultralytics.nn.modules.conv.Conv             [192, 64, 3, 1]               
 14                  -1  3    110976  ultralytics.nn.modules.conv.Conv             [64, 64, 3, 1]                
 15                  -1  1      2112  ultralytics.nn.modules.conv.Conv             [64, 32, 1, 1]                
 16                  -1  1      4128  torch.nn.modules.conv.ConvTranspose2d        [32, 32, 2, 2, 0]             
 17             [-1, 4]  1         0  ultralytics.nn.modules.conv.Concat           [1]                           
 18                  -1  1     27712  ultralytics.nn.modules.conv.Conv             [96, 32, 3, 1]                
 19                  -1  3     27840  ultralytics.nn.modules.conv.Conv             [32, 32, 3, 1]                
 20                  -1  1      9280  ultralytics.nn.modules.conv.Conv             [32, 32, 3, 2]                
 21            [-1, 15]  1         0  ultralytics.nn.modules.conv.Concat           [1]                           
 22                  -1  1     36992  ultralytics.nn.modules.conv.Conv             [64, 64, 3, 1]                
 23                  -1  3    110976  ultralytics.nn.modules.conv.Conv             [64, 64, 3, 1]                
 24                  -1  1     36992  ultralytics.nn.modules.conv.Conv             [64, 64, 3, 2]                
 25            [-1, 10]  1         0  ultralytics.nn.modules.conv.Concat           [1]                           
 26                  -1  1    147712  ultralytics.nn.modules.conv.Conv             [128, 128, 3, 1]              
 27                  -1  3    443136  ultralytics.nn.modules.conv.Conv             [128, 128, 3, 1]              
 28        [19, 23, 27]  1    607360  ultralytics.nn.modules.head.Detect           [80, [32, 64, 128]]           
YOLOv6n summary: 195 layers, 4,500,080 parameters, 4,500,064 gradients, 13.1 GFLOPs

TensorBoard: Start with 'tensorboard --logdir runs/detect/train11', view at http://localhost:6006/
Freezing layer 'model.28.dfl.conv.weight'
train: Scanning datasets/coco8/labels/train.cache... 4 images, 0 backgrounds, 0 corrupt: 100%|██████████| 4/4 [00:00<?, ?it/s]
val: Scanning datasets/coco8/labels/val.cache... 4 images, 0 backgrounds, 0 corrupt: 100%|██████████| 4/4 [00:00<?, ?it/s]
Plotting labels to runs/detect/train11/labels.jpg... 
optimizer: 'optimizer=auto' found, ignoring 'lr0=0.01' and 'momentum=0.937' and determining best 'optimizer', 'lr0' and 'momentum' automatically... 
optimizer: AdamW(lr=0.000119, momentum=0.9) with parameter groups 53 weight(decay=0.0), 62 weight(decay=0.0005), 61 bias(decay=0.0)
TensorBoard: model graph visualization added ✅
Image sizes 640 train, 640 val
Using 0 dataloader workers
Logging results to runs/detect/train11
Starting training for 1 epochs...

      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size
        1/1         0G      3.483      5.686      4.311         22        640: 100%|██████████| 1/1 [00:05<00:00,  5.91s/it]
                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 1/1 [00:02<00:00,  2.16s/it]
                   all          4         17          0          0          0          0

1 epochs completed in 0.006 hours.
Optimizer stripped from runs/detect/train11/weights/last.pt, 9.2MB
Optimizer stripped from runs/detect/train11/weights/best.pt, 9.2MB

Validating runs/detect/train11/weights/best.pt...
WARNING ⚠️ validating an untrained model YAML will result in 0 mAP.
Ultralytics 8.3.44 🚀 Python-3.10.12 torch-2.5.1+cu124 CPU (AMD Ryzen 3 3200G with Radeon Vega Graphics)
YOLOv6n summary (fused): 142 layers, 4,495,392 parameters, 0 gradients, 13.0 GFLOPs
                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 1/1 [00:01<00:00,  1.31s/it]
                   all          4         17          0          0          0          0
Speed: 4.7ms preprocess, 314.3ms inference, 0.0ms loss, 2.3ms postprocess per image
Results saved to runs/detect/train11
Traceback (most recent call last):
  File "main.py", line 91, in <module>
    detectImageWithYolo()
  File "main.py", line 70, in detectImageWithYolo
    model.save("yolov6coco.pt")
  File ".venv/lib/python3.10/site-packages/ultralytics/engine/model.py", line 414, in save
    torch.save({**self.ckpt, **updates}, filename)
TypeError: 'NoneType' object is not a mapping
```

### Environment

Ultralytics 8.3.44 🚀 Python-3.10.12 torch-2.5.1+cu124 CPU (AMD Ryzen 3 3200G with Radeon Vega Graphics)
Setup complete ✅ (4 CPUs, 23.3 GB RAM, 2769.5/3185.4 GB disk)
OS                  Linux-6.8.0-49-generic-x86_64-with-glibc2.35
Environment         Linux
Python              3.10.12
Install             pip
RAM                 23.35 GB
Disk                2769.5/3185.4 GB
CPU                 AMD Ryzen 3 3200G with Radeon Vega Graphics
CPU count           4
GPU                 None
GPU count           None
CUDA                None
numpy               ✅ 2.0.2>=1.23.0
numpy               ✅ 2.0.2<2.0.0; sys_platform == "darwin"
matplotlib          ✅ 3.9.2>=3.3.0
opencv-python       ✅ 4.10.0.84>=4.6.0
pillow              ✅ 11.0.0>=7.1.2
pyyaml              ✅ 6.0.2>=5.3.1
requests            ✅ 2.32.3>=2.23.0
scipy               ✅ 1.14.1>=1.4.1
torch               ✅ 2.5.1>=1.8.0
torch               ✅ 2.5.1!=2.4.0,>=1.8.0; sys_platform == "win32"
torchvision         ✅ 0.20.1>=0.9.0
tqdm                ✅ 4.67.1>=4.64.0
psutil              ✅ 6.1.0
py-cpuinfo          ✅ 9.0.0
pandas              ✅ 2.2.3>=1.1.4
seaborn             ✅ 0.13.2>=0.11.0
ultralytics-thop    ✅ 2.0.12>=2.0.0
{'OS': 'Linux-6.8.0-49-generic-x86_64-with-glibc2.35', 'Environment': 'Linux', 'Python': '3.10.12', 'Install': 'pip', 'RAM': '23.35 GB', 'Disk': '2769.5/3185.4 GB', 'CPU': 'AMD Ryzen 3 3200G with Radeon Vega Graphics', 'CPU count': 4, 'GPU': None, 'GPU count': None, 'CUDA': None, 'Package Info': {'numpy': '✅ 2.0.2<2.0.0; sys_platform == "darwin"', 'matplotlib': '✅ 3.9.2>=3.3.0', 'opencv-python': '✅ 4.10.0.84>=4.6.0', 'pillow': '✅ 11.0.0>=7.1.2', 'pyyaml': '✅ 6.0.2>=5.3.1', 'requests': '✅ 2.32.3>=2.23.0', 'scipy': '✅ 1.14.1>=1.4.1', 'torch': '✅ 2.5.1!=2.4.0,>=1.8.0; sys_platform == "win32"', 'torchvision': '✅ 0.20.1>=0.9.0', 'tqdm': '✅ 4.67.1>=4.64.0', 'psutil': '✅ 6.1.0', 'py-cpuinfo': '✅ 9.0.0', 'pandas': '✅ 2.2.3>=1.1.4', 'seaborn': '✅ 0.13.2>=0.11.0', 'ultralytics-thop': '✅ 2.0.12>=2.0.0'}}


### Minimal Reproducible Example

```
model = YOLO("yolov6n.yaml")
model.train(data="coco8.yaml", epochs=1, imgsz=640)
model.save("yolov6coco.pt")
```

### Additional

_No response_

### Are you willing to submit a PR?

- [ ] Yes I'd like to help by submitting a PR!


Hints:
👋 Hello @EmmanuelMess, thank you for your interest in Ultralytics 🚀! We appreciate you taking the time to report this issue. 

To help us investigate further, could you please confirm the reproducibility of this issue using the latest version of Ultralytics? You can upgrade with the command below:

```bash
pip install -U ultralytics
```

We also noticed that you've shared a reproducible example (thank you for that!). If the issue persists in the most recent version, this example will be very helpful for us to debug. Please also ensure that your `ultralytics` environment is aligned with our recommended setups:

### Environments

YOLO can be run in any of the following up-to-date verified environments (pre-installed with all necessary dependencies such as [CUDA](https://developer.nvidia.com/cuda)/[CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/) and [PyTorch](https://pytorch.org/)):

- **Notebooks** with free GPU: <a href="https://console.paperspace.com/github/ultralytics/ultralytics"><img src="https://assets.paperspace.io/img/gradient-badge.svg" alt="Run on Gradient"/></a> <a href="https://colab.research.google.com/github/ultralytics/ultralytics/blob/main/examples/tutorial.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"></a> <a href="https://www.kaggle.com/models/ultralytics/yolo11"><img src="https://kaggle.com/static/images/open-in-kaggle.svg" alt="Open In Kaggle"></a>
- **Google Cloud** Deep Learning VM. See [GCP Quickstart Guide](https://docs.ultralytics.com/yolov5/environments/google_cloud_quickstart_tutorial/)
- **Amazon** Deep Learning AMI. See [AWS Quickstart Guide](https://docs.ultralytics.com/yolov5/environments/aws_quickstart_tutorial/)
- **Docker Image**. See [Docker Quickstart Guide](https://docs.ultralytics.com/yolov5/environments/docker_image_quickstart_tutorial/) <a href="https://hub.docker.com/r/ultralytics/ultralytics"><img src="https://img.shields.io/docker/pulls/ultralytics/ultralytics?logo=docker" alt="Docker Pulls"></a>

### Join the Community

- For real-time debugging or discussions, join our [Discord](https://discord.com/invite/ultralytics) server 🎧.
- Share your insights or questions on [Discourse](https://community.ultralytics.com) or [Reddit](https://reddit.com/r/Ultralytics) to interact with the thriving community.

### Helpful Resources 

If you'd like to further explore concepts or troubleshoot other issues, check out our comprehensive [Docs](https://docs.ultralytics.com), including:
- [Model Training Tips](https://docs.ultralytics.com/guides/model-training-tips/)
- [Minimum Reproducible Example Guide](https://docs.ultralytics.com/help/minimum_reproducible_example/)

If this is a 🐛 bug as appears to be the case, an Ultralytics engineer will assist you soon to look deeper into the root cause. We'll stay on top of resolving this for you! 🔍😊

## Status

<a href="https://github.com/ultralytics/ultralytics/actions/workflows/ci.yaml?query=event%3Aschedule"><img src="https://github.com/ultralytics/ultralytics/actions/workflows/ci.yaml/badge.svg" alt="Ultralytics CI"></a> 

If this badge is green, all [Ultralytics CI](https://github.com/ultralytics/ultralytics/actions/workflows/ci.yaml?query=event%3Aschedule) tests are currently passing. CI tests run on macOS, Windows, and Ubuntu frequently to maintain performance and reliability.

Let us know how it goes! 🚀
The model is automatically saved during training inside the runs/detect folder. You don't need to use `model.save()`.
> The model is automatically saved during training inside the runs/detect folder. You don't need to use `model.save()`.

But I want to explicitly save it to a file. It works with YOLOv11, why not with v6?
It doesn't work if you load from yaml.
> It doesn't work if you load from yaml.

Thanks for the explanation, but it probably shouldn't crash. Maybe add an error message?

Patch:
diff --git a/ultralytics/engine/model.py b/ultralytics/engine/model.py
index db8d87ebc2..8affd958f2 100644
--- a/ultralytics/engine/model.py
+++ b/ultralytics/engine/model.py
@@ -115,7 +115,7 @@ def __init__(
         self.predictor = None  # reuse predictor
         self.model = None  # model object
         self.trainer = None  # trainer object
-        self.ckpt = None  # if loaded from *.pt
+        self.ckpt = {}  # if loaded from *.pt
         self.cfg = None  # if loaded from *.yaml
         self.ckpt_path = None
         self.overrides = {}  # overrides for trainer object
@@ -807,7 +807,7 @@ def train(
         # Update model and cfg after training
         if RANK in {-1, 0}:
             ckpt = self.trainer.best if self.trainer.best.exists() else self.trainer.last
-            self.model, _ = attempt_load_one_weight(ckpt)
+            self.model, self.ckpt = attempt_load_one_weight(ckpt)
             self.overrides = self.model.args
             self.metrics = getattr(self.trainer.validator, "metrics", None)  # TODO: no metrics returned by DDP
         return self.metrics


Test patch: