Memory-Efficient Gradient Unrolling for Large-Scale Bi-level Optimization