Test identical result between chunked prefill with single and multiple chunked. The return value in kv_cache_prefill function is key and value itself. Although the value of key and value are the same as stored in the KVCache without quantization, the prefill still produce slightly diffe
(self)
| 163 | |
| 164 | @pytest.mark.skip(reason="Can only pass on CPU.") |
| 165 | def test_chunked_prefill(self): |
| 166 | """Test identical result between chunked prefill with single and multiple chunked. |
| 167 | |
| 168 | The return value in kv_cache_prefill function is key and value itself. |
| 169 | Although the value of key and value are the same as stored in the KVCache without quantization, |
| 170 | the prefill still produce slightly different result while using multiple TPU devices or GPU due to unknown reasons. |
| 171 | """ |
| 172 | |
| 173 | prefill_length = 8 |
| 174 | tokens = jnp.array([1, 11, 22, 33, 444, 555, 666]) |
| 175 | padding_tokens = jnp.array([1, 11, 22, 33, 444, 555, 666, 0]) |
| 176 | true_length = tokens.shape[0] |
| 177 | assert padding_tokens.shape[0] == prefill_length |
| 178 | |
| 179 | def array_equal_valid_tokens(x, y, *, compare_length): |
| 180 | if len(x.shape) > 1: |
| 181 | # containing sequence |
| 182 | if x.shape[0] > 1: |
| 183 | # Assume batch size is 1 |
| 184 | # sequence is the first axis for kv cache |
| 185 | return jnp.array_equal(x[:compare_length], y[:compare_length]) |
| 186 | else: |
| 187 | # sequence is the second axis for decoder segment id |
| 188 | return jnp.array_equal(x[:, :compare_length], y[:, :compare_length]) |
| 189 | else: |
| 190 | # single integer |
| 191 | return jnp.array_equal(x, y) |
| 192 | |
| 193 | model_config_args = { |
| 194 | "max_target_length": prefill_length * 4, |
| 195 | "max_prefill_predict_length": prefill_length * 2, |
| 196 | "model_call_mode": "inference", |
| 197 | "capacity_factor": -1, |
| 198 | "decoder_block": "mistral", |
| 199 | "scan_layers": False, |
| 200 | "per_device_batch_size": 1.0, |
| 201 | } |
| 202 | |
| 203 | # Model without chunked prefill |
| 204 | config = self.init_pyconfig( |
| 205 | use_chunked_prefill=False, |
| 206 | **model_config_args, |
| 207 | ) |
| 208 | engine = MaxEngine(config) |
| 209 | params = engine.load_params() |
| 210 | expected_prefill_result, expected_first_token = engine.prefill( |
| 211 | params=params, |
| 212 | padded_tokens=padding_tokens, |
| 213 | true_length=true_length, |
| 214 | ) |
| 215 | |
| 216 | # Model with chunked prefill |
| 217 | config = self.init_pyconfig( |
| 218 | use_chunked_prefill=True, |
| 219 | **model_config_args, |
| 220 | ) |
| 221 | engine = MaxEngine(config) |
| 222 | params = engine.load_params() |
nothing calls this directly
no test coverage detected