@@ -1802,6 +1802,62 @@ def test_indexer_loss_kl_divergence_zero(self):
18021802
18031803 np .testing .assert_allclose (loss , 0.0 , atol = 1e-5 )
18041804
1805+ def test_indexer_with_approx_top_k (self ):
1806+ """Verify indexer runs with both approx and exact top-k."""
1807+ for use_approx in [False , True ]:
1808+ with self .subTest (indexer_use_approx_top_k = use_approx ):
1809+ mla_config_args = self .config_arguments .copy ()
1810+ mla_config_args ["use_indexer" ] = True
1811+ mla_config_args ["indexer_use_approx_top_k" ] = use_approx
1812+ mla_config_args ["indexer_topk" ] = 4 # Force indexer to run instead of returning early
1813+ mla_config_args ["attention" ] = "dot_product"
1814+
1815+ cfg , mla = self .init_mla (mla_config_args , rope_type = "default" )
1816+
1817+ lnx , decoder_segment_ids , decoder_positions = self .get_structured_data (cfg , cfg .dtype )
1818+
1819+ # Run forward pass which triggers indexer
1820+ out , _ = mla (
1821+ lnx ,
1822+ lnx ,
1823+ decoder_segment_ids = decoder_segment_ids ,
1824+ inputs_positions = decoder_positions ,
1825+ deterministic = True ,
1826+ model_mode = MODEL_MODE_TRAIN ,
1827+ )
1828+ self .assertIsNotNone (out )
1829+
1830+ def test_approx_top_k_recall (self ):
1831+ """Verify that approx_max_k meets the specified recall target compared to exact top_k."""
1832+ jax_rng = jax .random .PRNGKey (0 )
1833+
1834+ # We need a large enough N to make the approximation meaningful.
1835+ # Use shape [batch=4, queries=16, N=1024]
1836+ batch , queries , N = 4 , 16 , 1024
1837+ K = 64
1838+ recall_target = 0.95
1839+
1840+ # Generate random scores
1841+ scores = jax .random .normal (jax_rng , (batch , queries , N ))
1842+
1843+ # 1. Run exact Top-K
1844+ _ , true_indices = jax .lax .top_k (scores , k = K ) # [batch, queries, K]
1845+
1846+ # 2. Run approx Top-K
1847+ _ , approx_indices = jax .lax .approx_max_k (scores , k = K , recall_target = recall_target ) # [batch, queries, K]
1848+
1849+ # 3. Calculate Recall
1850+ # Broadcast compare true_indices [B, Q, K, 1] and approx_indices [B, Q, 1, K]
1851+ matches = (true_indices [..., None ] == approx_indices [..., None , :]).any (axis = - 1 ) # [B, Q, K]
1852+ num_matches = matches .sum (axis = - 1 ) # [B, Q]
1853+ actual_recalls = num_matches / K # [B, Q]
1854+ mean_recall = jnp .mean (actual_recalls )
1855+
1856+ print (f"\n Approx Top-K Recall Target: { recall_target } , Actual Mean Recall: { mean_recall :.4f} " )
1857+
1858+ # Assert that the actual recall is equal or exceeds the target.
1859+ self .assertGreaterEqual (mean_recall , recall_target )
1860+
18051861 def test_indexer_gradients (self ):
18061862 # Test that gradients do NOT flow back to inputs
18071863 bsz , seqlen = 2 , 8
0 commit comments