You could try to add another loop after the training epoch to calculate the training loss after the model was trained without further training. This would calculate the current training loss for this epoch without using the running average, which might create a bias.
Let me know, if this reduces the gap or not.
PS: you can post code snippets by wrapping them into three backticks ```