If you want to resume from partway through a dataset (and I’m assuming your dataset isn’t being shuffled or it’s meaningless to even try), then you just need to specify a starting point. e.g. have train(scheduler, optimizer, starting_step), initialise it to whatever you want outside of the epoch loop, and reset it to 0 at the end of the epoch. It’s a bit odd to pause and resume mid epoch, so the easiest way I can see is something like
if step <= starting_step:
    continue
else:
   # training loop goes here

If you forgot to set it to 0 at the end of an epoch, you’d only be training on a fixed data subset.
As for accessing validation loss from within another method, you could either once again pass it is an argument to train, or you could have a global variable (that would also go for starting_step).