Files
wehub-resource-sync ec436095dd
Book-CI / test (macos-latest) (push) Has been cancelled
Book-CI / test (ubuntu-latest) (push) Has been cancelled
Book-CI / test (windows-latest) (push) Has been cancelled
Release Fake Tag / publish (push) Has been cancelled
Deploy / deploy (macos-latest) (push) Has been cancelled
Deploy / deploy (ubuntu-latest) (push) Has been cancelled
Deploy / deploy (windows-latest) (push) Has been cancelled
Release to PyPI / Build & publish sglang-kt (push) Has been cancelled
Release to PyPI / Build kt-kernel (Python 3.11) (push) Has been cancelled
Release to PyPI / Build kt-kernel (Python 3.12) (push) Has been cancelled
Release to PyPI / Publish kt-kernel to PyPI (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:30:03 +08:00

112 lines
3.6 KiB
Python

'''
Description :
Author : Boxin Zhang
Version : 0.1.0
Copyright (c) 2024 by KVCache.AI, All Rights Reserved.
'''
from typing import Dict
import threading
import torch
import torch_npu
class NPUGraphRunner:
def __init__(self, deviceId):
torch.npu.set_compile_mode(jit_compile=False)
self.deviceId = deviceId
self.input_buffers: Dict[str, torch.Tensor] = {}
self.output_buffers: Dict[str, torch.Tensor] = {}
self.past_key_value = None
def init(self, batch_size, seq_length):
self.graph = torch.npu.NPUGraph()
self.main_stream = torch_npu.npu.Stream(device=self.deviceId)
self.share_experts_stream = torch_npu.npu.Stream(device=self.deviceId)
self.logits = torch.zeros((batch_size, seq_length, 7168), dtype=torch.float16).to(self.deviceId) # deepseekV3 hidden_size
self.workspace = None
self.model_capture = True
torch_npu.npu._subscribe_report(self.main_stream)
def destroy(self):
torch_npu.npu._unsubscribe_report(self.main_stream)
del self.graph
destory_runner(self.deviceId)
def capture(
self,
model,
cur_token,
position_ids,
cache_position,
past_key_values,
main_device,
**kwargs,
) -> None:
inputs_embeds = model.model.embed_tokens(cur_token.to("cpu")).to(main_device)
with torch.no_grad():
with torch.npu.graph(self.graph, stream=self.main_stream, auto_dispatch_capture=True):
logits = model(inputs_embeds=inputs_embeds,
position_ids=position_ids,
cache_position=cache_position,
past_key_values=past_key_values,
is_prefill=False,
**kwargs)
self.input_buffers = {
"inputs_embeds": inputs_embeds,
"position_ids": position_ids,
"cache_position": cache_position,
}
self.output_buffers = {
"logits": logits,
}
def forward(
self,
inputs_embeds,
position_ids,
cache_position,
) -> torch.Tensor:
thread = threading.Thread(target=self.graph.update, kwargs={"cpu_update_input": [{"actual_seq_lengths_kv": self.past_key_value.position}]})
thread.start()
self.input_buffers["inputs_embeds"].copy_(inputs_embeds)
self.input_buffers["position_ids"].copy_(position_ids)
self.input_buffers["cache_position"].copy_(cache_position)
torch_npu.npu.synchronize()
with torch_npu.npu.stream(self.main_stream):
# Run the graph.
self.graph.replay()
thread.join()
# Return the output tensor.
return self.output_buffers["logits"]
def launch_callback(self, func, data, block, stream):
torch_npu.npu._launch_host_func(stream, func, data)
def __call__(self, *args, **kwargs):
return self.forward(*args, **kwargs)
runner_dict = dict()
def check_runner(deviceId: int):
runner = runner_dict.get(deviceId)
if runner is None:
return True
else:
return False
def destory_runner(deviceId: int):
# print("the new NPUGraphRunner and deviceId is ", deviceId)
runner = runner_dict.get(deviceId)
if runner is not None:
runner_dict[deviceId] = None
def get_or_create_runner(deviceId: int):
runner = runner_dict.get(deviceId)
if runner is None:
runner = NPUGraphRunner(deviceId)
runner_dict[deviceId] = runner
return runner