So I have a basic ship and essentially, i want the ship to "level up".
both ships are different prefabs within the scene, and I don't know the best way to actually handle this.
Should i go ahead and instance them in the start function with an empty game object serving as my initial position?
There are a couple of approaches you could follow for this and which one is the best depends on your specific needs. In particular, it depends largely on how different your different ships are and how you have the logic put into scripts.
One approach that I think should work pretty "generally":
Create prefabs with only models for the different "ships"
If needed, have a "property script" that keeps your specific settings (e.g. speed, ammunition, characteristics of weapons etc.)
Have a "ControllerPrefab" that is just an (empty) game object with all your scripts that handle the behavior of the ships/characters attached
Have "slots" for all ship/character prefabs on that controller prefab
Have a "default ship" (which you use when you first instantiate your ControllerPrefab)
When the ControllerPrefab is instantiated, immediately instantiate the "default ship"
When you switch (or instantiate the default ship), destroy anything that's below your ControllerPrefab (if there is anything ;-) )
Instantiate your new "ship" and use transform.parent to attach your model prefab to the ControllerPrefab
Make sure to set the references in your ControllerPrefab-scripts that need access to the "specific configurations" to your new prefab
With that kind of approach, you could also set up LOD-systems comparatively easily.