22
33The serving model (``KerasHubForCausalLM`` in this package, registered
44with vLLM by tpu-inference's plugin hook) publishes this
5- context around each forward step with ``vllm_context_scope``, which clears
6- it on exit even when the forward raises, all on one thread. KerasHub
7- attention layers, the paged-attention bridge, and ``PositionEmbedding`` read
8- it in-place, so serving metadata never has to thread through layer
9- signatures.
5+ context around each forward step with ``vllm_context_scope``, which restores
6+ the prior state on exit even when the forward raises, all on one thread.
7+ KerasHub attention layers, the paged-attention bridge, and
8+ ``PositionEmbedding`` read it in-place, so serving metadata never has to
9+ thread through layer signatures.
1010
1111It is thread-local so concurrent requests on separate worker threads never see
1212each other's caches, positions, or kernel: each thread gets its own inactive
1616import contextlib
1717import threading
1818
19+ # The single enumeration of the context's fields and their inactive values.
20+ # `VLLMContext.__init__`, `clear_vllm_context`, and the scope's save/restore
21+ # all derive from it, so adding a field means touching exactly one place.
22+ _INACTIVE_STATE = {
23+ "paged_attention_func" : None ,
24+ "positions" : None ,
25+ "kv_caches" : None ,
26+ "updated_kv_caches" : None ,
27+ "layer_index" : 0 ,
28+ "active" : False ,
29+ }
30+
31+
32+ def _reset (context ):
33+ """Puts ``context`` into the inactive state."""
34+ for name , value in _INACTIVE_STATE .items ():
35+ setattr (context , name , value )
36+
1937
2038class VLLMContext (threading .local ):
2139 """Thread-local context for passing serving metadata to Keras layers.
2240
2341 Attributes:
24- block_tables: The block tables tensor for paged attention.
25- slot_mapping: The slot mapping tensor for paged attention.
26- attention_metadata: The full attention metadata object from vLLM.
27- paged_attention_func: The compiled paged-attention kernel.
28- mesh: The JAX device mesh required by the paged attention kernel.
42+ paged_attention_func: The paged-attention closure published by the
43+ serving model; engine details are already bound inside it.
2944 positions: vLLM's per-token absolute position ids (for RoPE models).
3045 kv_caches: Per-layer paged KV caches for the current forward step.
3146 Attention layers consume these in call order via `layer_index`,
@@ -40,69 +55,40 @@ class VLLMContext(threading.local):
4055 def __init__ (self ):
4156 """Initializes an empty inactive context."""
4257 super ().__init__ ()
43- self .block_tables = None
44- self .slot_mapping = None
45- self .attention_metadata = None
46- self .paged_attention_func = None
47- self .mesh = None
48- self .positions = None
49- self .kv_caches = None
50- self .updated_kv_caches = None
51- self .layer_index = 0
52- self .active = False
58+ _reset (self )
5359
5460
5561_vllm_context = VLLMContext ()
5662
5763
5864def set_vllm_context (
59- block_tables ,
60- slot_mapping ,
61- attention_metadata = None ,
6265 paged_attention_func = None ,
63- mesh = None ,
6466 positions = None ,
6567 kv_caches = None ,
6668):
6769 """Sets the thread-local vLLM context parameters.
6870
6971 Args:
70- block_tables: Array representing memory blocks for key/value caching.
71- slot_mapping: Array mapping sequence tokens to cache slots.
72- attention_metadata: Additional hardware/framework specific metadata.
73- paged_attention_func: The function to use for paged attention.
74- mesh: The JAX device mesh the paged attention kernel shards across.
72+ paged_attention_func: The paged-attention closure to dispatch to.
7573 positions: vLLM's per-token absolute position ids (used by RoPE models
7674 to apply rotary embeddings at the correct positions under paged /
7775 continuous-batched decode).
7876 kv_caches: Per-layer paged KV caches, in transformer-layer order.
7977 """
80- _vllm_context .block_tables = block_tables
81- _vllm_context .slot_mapping = slot_mapping
82- _vllm_context .attention_metadata = attention_metadata
8378 _vllm_context .paged_attention_func = paged_attention_func
84- _vllm_context .mesh = mesh
8579 _vllm_context .positions = positions
8680 _vllm_context .kv_caches = list (kv_caches ) if kv_caches is not None else None
8781 _vllm_context .updated_kv_caches = (
8882 list (kv_caches ) if kv_caches is not None else None
8983 )
9084 _vllm_context .layer_index = 0
85+ # Set last, so a failure partway through can never look half-active.
9186 _vllm_context .active = True
9287
9388
9489def clear_vllm_context ():
95- """Clears the thread-local vLLM context."""
96- _vllm_context .block_tables = None
97- _vllm_context .slot_mapping = None
98- _vllm_context .attention_metadata = None
99- _vllm_context .paged_attention_func = None
100- _vllm_context .mesh = None
101- _vllm_context .positions = None
102- _vllm_context .kv_caches = None
103- _vllm_context .updated_kv_caches = None
104- _vllm_context .layer_index = 0
105- _vllm_context .active = False
90+ """Resets the thread-local vLLM context to its inactive state."""
91+ _reset (_vllm_context )
10692
10793
10894def get_vllm_context ():
@@ -116,30 +102,25 @@ def get_vllm_context():
116102
117103@contextlib .contextmanager
118104def vllm_context_scope (
119- block_tables ,
120- slot_mapping ,
121- attention_metadata = None ,
122105 paged_attention_func = None ,
123- mesh = None ,
124106 positions = None ,
125107 kv_caches = None ,
126108):
127109 """Publishes the serving context for the enclosed forward step.
128110
129- Sets the thread-local context on entry and always clears it on exit,
130- including when the forward raises, so a reused worker thread can never
131- observe a stale context. Arguments match ``set_vllm_context``.
111+ Saves the prior state on entry and always restores it on exit,
112+ including when the forward raises — so a reused worker thread can never
113+ observe a stale context, and nested scopes hand back the outer scope's
114+ state instead of wiping it. Arguments match ``set_vllm_context``.
132115 """
116+ previous = {name : getattr (_vllm_context , name ) for name in _INACTIVE_STATE }
133117 set_vllm_context (
134- block_tables = block_tables ,
135- slot_mapping = slot_mapping ,
136- attention_metadata = attention_metadata ,
137118 paged_attention_func = paged_attention_func ,
138- mesh = mesh ,
139119 positions = positions ,
140120 kv_caches = kv_caches ,
141121 )
142122 try :
143123 yield
144124 finally :
145- clear_vllm_context ()
125+ for name , value in previous .items ():
126+ setattr (_vllm_context , name , value )
0 commit comments