def update(self, present_kvs: list[OrtValue]):
        """Update the cache with the present key-value tensors.

        At the prompt processing step, i.e., when the cache is empty, the present key-value tensors can have any length
        smaller than or equal to max_cache_len.
        In token generation step, i.e. with one new token at each step, the present key-value tensors must have length
        equal to max_cache_len + 1. The last key-value tensor at the end of present_kvs is inserted into the first empty
        slot in the cache.

        :param present_kvs: List of present key-value tensors as OrtValue.
        """
        if self.seen_len == 0:
            # prompt processing
            present_len = present_kvs[0].shape()[2]
            assert present_len > 0, "present_kvs cannot be empty"
            assert present_len <= self.max_cache_len, (
                "present_kvs is longer than max_cache_len during prompt processing"
            )
            for k, v in zip(self.past_names, present_kvs):
                if self.backend == "torch":
                    import torch

                    self.cache[k][:, :, :present_len] = torch.tensor(v.numpy(), device=self.torch_device)
                else:
                    np_value = self.cache[k].numpy()
                    np_value[:, :, :present_len] = v.numpy()
                    self.cache[k].update_inplace(np_value)
            self.seen_len = present_len
            return

        # token generation
        for past_k, present_k, v in zip(self.past_names, self.present_names, present_kvs):
            assert self.output_cache[present_k].data_ptr() == v.data_ptr(), (
                "out cache ortvalue should be same as present ortvalue"
            )
            if self.backend == "torch":
                self.cache[past_k][:, :, self.seen_len] = self.output_cache[present_k][:, :, -1]
            else:
                np_value = self.cache[past_k].numpy()
                np_value[:, :, self.seen_len] = v.numpy()[:, :, -1]
                self.cache[past_k].update_inplace(np_value)
        self.seen_len += 1
Update the cache with the present key-value tensors.

        At the prompt processing step, i.e., when the cache is empty, the present key-value tensors can have any length
        smaller than or equal to max_cache_len.
        In token generation step, i.e. with one new token at each step, the present key-value tensors must have length
        equal to max_cache_len + 1. The last key-value tensor at the end of present_kvs is inserted into the first empty
        slot in the cache.

        :param present_kvs: List of present key-value tensors as OrtValue.
        
examples/utils/kv_cache_utils.py