Neither. You want to load a single tile sheet once and load that single texture into the GPU with no cropping or copying.
It's most efficient to actually draw from the tile sheet by figuring out the correct UV coordinates for a sprite in the sheet and then passing those to your draw commands. Individual textures should be avoided if you can, at least for small sprites and frequently-used textures.
You want to avoid any excess state switches and minimize draw calls. This means that you ideally want to only bind a single texture (the one sprite sheet) instead of many individual textures. It also means you ideally want to submit a single draw call (maybe an instanced call) for all your game objects that just use that single texture, instead of needing a separate draw call for each individual sprite (or worse, each individual object). Actually achieving a single state and a single draw call becomes impossible as your game gets more complex, but you want to keep the numbers as low as possible.
You only want to bind the texture once, since it'll be the same spritesheet texture for all sprites. The rest is figuring out the correct UVs. If sprite metadata says that some 500x500 image is located at position (1500,500) within a 3000x3000 spritesheet, then you know that the opposite corners are at (1500,500) and (2000,1000). Divide those by the sprite sheet dimensions to get the normalized UV coordinates, (1/2,1/6) and (2/3,1/3). When you draw the object, use those UVs (and extrapolate to get the other two corners). Ideally, you don't want to draw each object but rather fill a dynamic buffer with position and texcoord information and then draw all your objects (maybe with instancing) using a single draw call sourcing that dynamic buffer.