All notable changes to FastFace. Format loosely follows [Keep a Changelog]. Dates are when each tag was cut. Underlying sprint numbers link to the git history for details.
Quality improvement release. INT8 now beats FP32 on LFW 10-fold verification (previously tied).
Notable calibration refinements across S82-S108:
- S85 trailing-BN-after-Gemm fold bug fix (+0.006 cos-sim). Was a latent bug producing per-Gemm-output mis-scaling on the 512-dim embedding.
- S88 scaled to N_CALIB=200 (previously 100) for tighter p99.9 percentile estimation.
- S91 outlier inclusion (
WITH_PRINCESS=1): force-includePrincess_Elisabeth_0001.jpgin calibration batch. Her cos-sim rises from 0.888 to 0.990 and the whole distribution lifts 0.001-0.003.
LFW 10-fold:
- INT8: 99.650% +/- 0.229% (was 99.633% in v1.0.0)
- FP32: 99.633% +/- 0.221% (ORT reference, unchanged)
- INT8 - FP32 = +0.017 pp (INT8 now wins by one pair out of 6000)
Negative-result KB entries committed (S82-S108, see sprint_work/kb/):
SmoothQuant, weight percentile, depth-aware percentile, ensemble,
KL calibration, flip augmentation, DFQ cross-layer equalization.
Speed and footprint unchanged from v1.0.0:
- b=1 burst: 13.27 ms/face
- B=8 batched: 11.09 ms/face
- Peak RSS: 90 MB
- Binary: 96 KB
First production-ready release. All 6 validation suites green:
make clean && make all— builds fastface_int8.exe, fastface_int8_batched.exe, libfastface.amake test— regression PASS (bit-exact vs golden)go test ./go/fastface— PASS including 2-goroutine concurrent testpython fastface.pyself-test — PASS (Python SDK bit-exact)libfastface.aconsumer test — PASS (C API bit-exact)face_match.pydemo — SAME/DIFFERENT verdicts correct
Operating-point matrix (i7-13700, AVX-VNNI):
| mode | median | sustained | drift | use case |
|---|---|---|---|---|
b=1 --threads 8 |
13.27 ms | 75 face/s | small | burst / interactive |
b=1 --threads 4 |
20.50 ms | 48 face/s | ZERO | 24/7 low-throughput |
B=8 --threads 8 |
13.02 ms/face | 77 face/s | small | bursty batched |
B=8 --threads 4 |
17.49 ms/face | 57 face/s ∞ | ZERO | 24/7 production |
Quality: LFW 10-fold 99.633 ± 0.221% (identical to FP32). Footprint: 96 KB exe + 42 MB weights, 90 MB peak RSS (4× less than ORT). SDKs: Python, C library (libfastface.a), Go (no cgo), stdin/stdout pipe.
Covers S65-S74 polish: Makefile, CHANGELOG, LICENSE placeholder, .gitignore, thermal-stable mode, concurrent test, Go example, RSS metric.
Verification benchmark: INT8 matches FP32 accuracy identically on LFW.
- Added
bench_lfw_verify.py(and S57bench_lfw_full.py10-fold). - Measured best-threshold accuracy 99.50% (both engines), TAR@FAR=1% 99.20%, AUC 0.99866 INT8 / 0.99873 FP32 — 0.00007 gap.
- S57 6000-pair 10-fold: 99.633% ± 0.221%, gap 0.000 pp.
- S59 augmentation robustness: INT8 tracks FP32 within ±0.2 pp under Gaussian blur, noise, and JPEG compression.
Batched INT8 driver: 11.09 ms/face at B=8, 2.84× ORT, 90 face/s.
- Added
arcface_forward_int8_batched.cwith--batch NCLI. - New
fastface_conv2d_i8_nhwc_batchedkernel packs B im2cols into one VNNI GEMM (amortizes weight loads). - S58 added
--servermode to batched driver for streaming pipelines.
First ship-quality milestone: cos-sim 0.986 + 2.368× ORT at b=1.
- S36 phase A:
fused_epilogue_int8accepts optional per-channelinv_out.arcface_forward_int8.cloads OPSC2 per-channel scale file. - S37 partial fold: final Gemm weights pre-folded with per-channel input
activation scale (
prepare_weights_v3.py→ FFW4 format). - S38 full coherent per-channel pipeline: every Conv's weights pre-
folded, runtime
in_scale = 1.0for all Convs, per-channelinv_outandadd_scale_per_chplumbed through the epilogue. cos-sim jumped 0.954 → 0.986 on single face; multi-face mean 0.986. - S39-S43 calibration tuning: locked N_CALIB=100, PERCENTILE=99.9 (97/100 LFW faces ≥ 0.98).
- S44 1x1 direct-conv fast path.
- S48 P-core affinity (0x5555) preferred over HT.
INT8 13.36 ms / 2.355× ORT via VNNI matvec + ADD fusion.
- S30 per-op profile: OP_GEMM = 24% scalar bottleneck, OP_ADD = 27% (24 standalone requant passes).
- S31
fastface_gemm_i8_matvec_vnni: uint8/int8dpbusdXOR-0x80 trick for the final 25088→512 Linear. Saved 7 ms. - S32 fused ADD shortcut into Conv epilogue. Saved 7 ms + improved cos-sim (fewer intermediate requants). 13.36 ms, 2.355× ORT, 20/20 wins on interleaved stable bench.
- S34-S35 INT8 Winograd F(2,3) moonshot aborted — VNNI int8 beats int16 madd on AVX-VNNI. Scalar ref proved bit-exact but AVX2 version was 0.66× (SLOWER than VNNI direct). Documented.
- Stable bench protocol (20 interleaved runs, 3 s cooldown, HIGH priority).
- FP32 driver S17-S29d reached 25.93 ms / 1.21× ORT, cos-sim 0.9997. Still the "ship-FP32" path when INT8 drift is unacceptable.
- FP32 Winograd F(2,3) + packed AVX2 GEMM first landed here.
- 29 ms / 1.09× ORT on the standard stable bench.
- ARM NEON port — recon in
sprint_work/PORTING_ARM_NEON.md. - Face detector + alignment (RetinaFace INT8) for end-to-end pipeline.
- Bitstream-domain face detection (unique moat per BZ research).
| language | module | call style |
|---|---|---|
| Python | fastface.py |
FastFace().embed(arr) |
| C / C++ | libfastface.a + fastface.h |
fastface_create/embed/destroy |
| Go | go/fastface/ |
fastface.New().Embed(input) |
| Any | fastface_int8.exe --server |
stdin/stdout fp32 stream |