You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
log and rsqrt epsilon defaults underflow to zero in fp16, so folding returns inf #2886
Both values are representable in fp32, but np.float16(1e-12) and np.float16(1e-45) are both exactly 0.0. So in fp16 the epsilon the docstrings describe as "a small constant added for stability" is removed entirely, and constant folding returns infinities:
epsilon folded value for x = [0.0, 1e-8]
rsqrt fp16 0.0 [inf inf]
rsqrt fp32 1e-12 [1.0000e+06 9.9995e+03]
log fp16 0.0 [-inf -inf]
log fp32 1e-45 [-103.27893 -18.420681]
fp16 is the dtype most Core ML models are converted to, so the stabilizer is missing in the case it exists for.
While narrowing this down I found that constant folding and the runtime disagree for fp32 rsqrt, independently of the fp16 problem. The same op, with the same input, gives different answers depending on whether the input is known at convert time:
The folded path matches the documented y = 1 / sqrt(x + epsilon) with epsilon = 1e-12. The runtime behaves as though epsilon is roughly 2**-24 (~6e-08). That is a 244x difference at x = 0.
I have not filed that as a separate issue because I cannot tell which side is intended, and the runtime is not something coremltools can change. If the runtime's epsilon is deliberate, then value_inference is producing values the hardware will never reproduce, which seems worth deciding on explicitly. Happy to split it out if you'd prefer.
Interestingly, the fp16 fix in the linked PR makes fp16 rsqrt(0) fold to 4096.0 — the same value the runtime returns — so for fp16 the two paths end up agreeing.
Activity