I would recommend to narrow down the issue of a low utilization first.
If you’ve removed the data loading and use a random CUDATensor, the utilization should be higher.
At least if your code is not bottlenecked by anything else, so try to remove all unnecessary code and just keep the training (forward, backward, and optimizer).