---
title: "ClikaRT::ops::qk_layer_norm"
sidebar_label: "qk_layer_norm"
description: "Per-head LAYER norm over packed attention projections, the mean-subtracting sibling of qk_rms_norm."
---

<!-- Generated by tools/doxygen2mdx from Doxygen XML. Do not edit. -->

<span class="api-kind api-kind--function">function</span>

## qk\_layer\_norm() {#qk_layer_norm}

<div class="api-signature">

`std::array<`[`Tensor`](../Tensor.md) `3>` **`qk_layer_norm`**(<br />
&nbsp;&nbsp;&nbsp;&nbsp;[`Tensor`](../Tensor.md) `query`,<br />
&nbsp;&nbsp;&nbsp;&nbsp;[`OptionalTensor`](../../index.md#OptionalTensor) `key` `=` `{}`,<br />
&nbsp;&nbsp;&nbsp;&nbsp;[`OptionalTensor`](../../index.md#OptionalTensor) `value` `=` `{}`,<br />
&nbsp;&nbsp;&nbsp;&nbsp;[`OptionalTensor`](../../index.md#OptionalTensor) `query_weight` `=` `{}`,<br />
&nbsp;&nbsp;&nbsp;&nbsp;[`OptionalTensor`](../../index.md#OptionalTensor) `query_bias` `=` `{}`,<br />
&nbsp;&nbsp;&nbsp;&nbsp;[`OptionalTensor`](../../index.md#OptionalTensor) `key_weight` `=` `{}`,<br />
&nbsp;&nbsp;&nbsp;&nbsp;[`OptionalTensor`](../../index.md#OptionalTensor) `key_bias` `=` `{}`,<br />
&nbsp;&nbsp;&nbsp;&nbsp;`std::int64_t` `head_dim` `=` `0`,<br />
&nbsp;&nbsp;&nbsp;&nbsp;`std::optional<double>` `eps` `=` `std::nullopt`<br />
)

</div>

Per-head LAYER norm over packed attention projections, the mean-subtracting sibling of [`qk_rms_norm`](./qk_rms_norm.md#qk_rms_norm).

Each contiguous `head_dim` run of `query` (and `key`, when present) is normalized as `(x - `[`mean`](./mean.md#mean)`) / `[`sqrt`](./sqrt.md#sqrt)`(`[`var`](./var.md#var)` + eps) * w + b`; `value`, when given, is normalized the same way with no weight and no bias (it has no affine slots).

**Parameters**

- `query`: the query projection, `[.., heads*head_dim]`.
- `key`: optional key projection, same trailing structure.
- `value`: optional value projection, same trailing structure; normalized affine-less when given.
- `query_weight`: optional per-head gain for `query`, shape `[head_dim]`.
- `query_bias`: optional per-head shift for `query`, shape `[head_dim]`.
- `key_weight`: optional per-head gain for `key`, shape `[head_dim]`.
- `key_bias`: optional per-head shift for `key`, shape `[head_dim]`.
- `head_dim`: the per-head run length; must divide the trailing extent.
- `eps`: stability floor; `std::nullopt` selects 1e-5.

**Returns:** `{q_normed, k_normed, v_normed}`; absent inputs come back absent.

**Throws**

- `ClikaRT::Error`: (`INVALID_ARGUMENT`) when `head_dim` does not divide the trailing extent or an affine operand is mis-shaped.

<div class="api-declared">

Declared in `ClikaRT/compute/ops.h`, line 3659

</div>
