Spaces:
Running
Running
| export function layerNormRows( | |
| input: Float32Array, | |
| width: number, | |
| epsilon = 1e-5, | |
| ): Float32Array { | |
| if (!Number.isInteger(width) || width <= 0 || input.length % width !== 0) { | |
| throw new Error(`layerNormRows width ${width} does not divide input length ${input.length}.`) | |
| } | |
| const output = new Float32Array(input.length) | |
| for (let offset = 0; offset < input.length; offset += width) { | |
| let mean = 0 | |
| for (let index = 0; index < width; index += 1) mean += input[offset + index] | |
| mean /= width | |
| let variance = 0 | |
| for (let index = 0; index < width; index += 1) { | |
| const centered = input[offset + index] - mean | |
| variance += centered * centered | |
| } | |
| const inverseStandardDeviation = 1 / Math.sqrt(variance / width + epsilon) | |
| for (let index = 0; index < width; index += 1) { | |
| output[offset + index] = (input[offset + index] - mean) * inverseStandardDeviation | |
| } | |
| } | |
| return output | |
| } | |
| export interface TensorComparison { | |
| count: number | |
| maxAbsoluteError: number | |
| meanAbsoluteError: number | |
| rmse: number | |
| cosineSimilarity: number | |
| finite: boolean | |
| } | |
| export function compareFloat32(reference: Float32Array, candidate: Float32Array): TensorComparison { | |
| if (reference.length !== candidate.length) { | |
| throw new Error(`Tensor lengths differ: reference=${reference.length}, candidate=${candidate.length}.`) | |
| } | |
| let maxAbsoluteError = 0 | |
| let absoluteErrorSum = 0 | |
| let squaredErrorSum = 0 | |
| let dot = 0 | |
| let referenceSquared = 0 | |
| let candidateSquared = 0 | |
| let finite = true | |
| for (let index = 0; index < reference.length; index += 1) { | |
| const expected = reference[index] | |
| const actual = candidate[index] | |
| if (!Number.isFinite(expected) || !Number.isFinite(actual)) finite = false | |
| const delta = actual - expected | |
| const absolute = Math.abs(delta) | |
| maxAbsoluteError = Math.max(maxAbsoluteError, absolute) | |
| absoluteErrorSum += absolute | |
| squaredErrorSum += delta * delta | |
| dot += expected * actual | |
| referenceSquared += expected * expected | |
| candidateSquared += actual * actual | |
| } | |
| const denominator = Math.sqrt(referenceSquared * candidateSquared) | |
| return { | |
| count: reference.length, | |
| maxAbsoluteError, | |
| meanAbsoluteError: reference.length > 0 ? absoluteErrorSum / reference.length : 0, | |
| rmse: reference.length > 0 ? Math.sqrt(squaredErrorSum / reference.length) : 0, | |
| cosineSimilarity: denominator > 0 ? dot / denominator : 1, | |
| finite, | |
| } | |
| } | |