Inconsistency Issues With Stepper Motor
Several possibilities:

You might try adding delays to get 50% duty cycle as suggested by jonk. 
...
GPIO.output(21,true)
time.sleep(0.01)
GPIO.output(21,false)
time.sleep(0.01)
...

You might also try adding acceleration and deceleration ramps to your code and using an Arduino library that supports them (like AccelStepper).

Also, context switching on the Raspberry Pi will cause non-uniformity in the timing of the step pulse train which translates to asking the motor to accelerate and decelerate very quickly which may exceed the motor's torque capabilities.  Stepper motor's torque generally drops with rotational speed but usually has a resonance band where torque drops to near zero at a certain speed range.  Putting a flywheel on the shaft (or other load with a bit of angular inertia) can minimize the resonance effect.