laya 0.3.2__tar.gz → 0.3.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: laya
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: Fast, non-autoregressive System 1 decision engine with calibrated probabilities
5
5
  Author: Convai Innovations
6
6
  License: Apache-2.0
@@ -246,10 +246,39 @@ Precedence, highest first:
246
246
  5. Detected script (exact) and, for Latin text, a stopword/diacritic language guess (best effort).
247
247
  6. `default=` (`"english"` unless you change it).
248
248
 
249
+ ### Preload — make routing free
250
+
251
+ A cold checkpoint build costs **seconds**; language detection costs **microseconds**. At the
252
+ default `max_loaded=1`, traffic that alternates languages rebuilds a model on *every* request.
253
+ For a server or a demo, preload:
254
+
255
+ ```python
256
+ router = Router(preload=True) # every checkpoint resident, routing is free
257
+ router = Router(preload=True, device="cuda")
258
+ router.preload(["english", "multilingual"]) # or just the two you serve
259
+ ```
260
+
261
+ `preload` raises `max_loaded` to fit what it built, so the LRU cannot evict it immediately.
262
+
263
+ If the process already has a checkpoint loaded for other reasons, hand it over instead of
264
+ loading a second copy:
265
+
266
+ ```python
267
+ router.attach("english", existing_agent) # no duplicate 421M parameters
268
+ router.preload() # builds only what is still missing
269
+ ```
270
+
271
+ Measured on CPU with the demo Space's own workload:
272
+
273
+ | | per request | model loads |
274
+ |---|---|---|
275
+ | `Router()` — lazy, `max_loaded=1` | 4–6 s on every language switch | 1 per switch |
276
+ | `Router(preload=True)` | **193–464 ms** | **none** |
277
+
249
278
  ### Memory
250
279
 
251
- All three together are ~1.16B parameters, so `Router` keeps **one** resident by default and
252
- evicts least-recently-used:
280
+ All three together are ~1.16B parameters (~4.6 GB fp32), so `Router` keeps **one** resident by
281
+ default and evicts least-recently-used. Raise it when you have the RAM:
253
282
 
254
283
  ```python
255
284
  Router(max_loaded=2) # keep two hot
@@ -216,10 +216,39 @@ Precedence, highest first:
216
216
  5. Detected script (exact) and, for Latin text, a stopword/diacritic language guess (best effort).
217
217
  6. `default=` (`"english"` unless you change it).
218
218
 
219
+ ### Preload — make routing free
220
+
221
+ A cold checkpoint build costs **seconds**; language detection costs **microseconds**. At the
222
+ default `max_loaded=1`, traffic that alternates languages rebuilds a model on *every* request.
223
+ For a server or a demo, preload:
224
+
225
+ ```python
226
+ router = Router(preload=True) # every checkpoint resident, routing is free
227
+ router = Router(preload=True, device="cuda")
228
+ router.preload(["english", "multilingual"]) # or just the two you serve
229
+ ```
230
+
231
+ `preload` raises `max_loaded` to fit what it built, so the LRU cannot evict it immediately.
232
+
233
+ If the process already has a checkpoint loaded for other reasons, hand it over instead of
234
+ loading a second copy:
235
+
236
+ ```python
237
+ router.attach("english", existing_agent) # no duplicate 421M parameters
238
+ router.preload() # builds only what is still missing
239
+ ```
240
+
241
+ Measured on CPU with the demo Space's own workload:
242
+
243
+ | | per request | model loads |
244
+ |---|---|---|
245
+ | `Router()` — lazy, `max_loaded=1` | 4–6 s on every language switch | 1 per switch |
246
+ | `Router(preload=True)` | **193–464 ms** | **none** |
247
+
219
248
  ### Memory
220
249
 
221
- All three together are ~1.16B parameters, so `Router` keeps **one** resident by default and
222
- evicts least-recently-used:
250
+ All three together are ~1.16B parameters (~4.6 GB fp32), so `Router` keeps **one** resident by
251
+ default and evicts least-recently-used. Raise it when you have the RAM:
223
252
 
224
253
  ```python
225
254
  Router(max_loaded=2) # keep two hot
@@ -22,7 +22,7 @@ from .presets import (
22
22
  )
23
23
  from .router import DEFAULT_MODELS, RouteDecision, Router
24
24
 
25
- __version__ = "0.3.2"
25
+ __version__ = "0.3.3"
26
26
  __all__ = [
27
27
  "Agent",
28
28
  "RLAgent",
@@ -194,6 +194,19 @@ class Router:
194
194
  if k not in self._order:
195
195
  self._agents.pop(k, None)
196
196
 
197
+ def attach(self, name: str, agent: Any):
198
+ """Register an already-built Agent under `name` instead of loading a second copy.
199
+
200
+ Useful when the process has a checkpoint loaded for other reasons: a demo that already
201
+ built `convaiinnovations/laya` can hand it to the router rather than pay for -- and hold
202
+ in memory -- a duplicate 421M parameters.
203
+ """
204
+ key = normalise_name(name)
205
+ self._agents[key] = agent
206
+ self._touch(key)
207
+ self.max_loaded = max(self.max_loaded, len(self._agents))
208
+ return agent
209
+
197
210
  def preload(self, names: Optional[List[str]] = None):
198
211
  """Download and build checkpoints up front so no request ever pays a model load.
199
212
 
@@ -203,9 +216,10 @@ class Router:
203
216
  the LRU would immediately evict what this just built.
204
217
  """
205
218
  names = [normalise_name(n) for n in (names or list(self.models))]
206
- self.max_loaded = max(self.max_loaded, len(names))
219
+ self.max_loaded = max(self.max_loaded, len(names), len(self._agents))
207
220
  for n in names:
208
- self.load(n)
221
+ if n not in self._agents: # an attached agent is already built
222
+ self.load(n)
209
223
  return self
210
224
 
211
225
  def unload(self, name: Optional[str] = None):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: laya
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: Fast, non-autoregressive System 1 decision engine with calibrated probabilities
5
5
  Author: Convai Innovations
6
6
  License: Apache-2.0
@@ -246,10 +246,39 @@ Precedence, highest first:
246
246
  5. Detected script (exact) and, for Latin text, a stopword/diacritic language guess (best effort).
247
247
  6. `default=` (`"english"` unless you change it).
248
248
 
249
+ ### Preload — make routing free
250
+
251
+ A cold checkpoint build costs **seconds**; language detection costs **microseconds**. At the
252
+ default `max_loaded=1`, traffic that alternates languages rebuilds a model on *every* request.
253
+ For a server or a demo, preload:
254
+
255
+ ```python
256
+ router = Router(preload=True) # every checkpoint resident, routing is free
257
+ router = Router(preload=True, device="cuda")
258
+ router.preload(["english", "multilingual"]) # or just the two you serve
259
+ ```
260
+
261
+ `preload` raises `max_loaded` to fit what it built, so the LRU cannot evict it immediately.
262
+
263
+ If the process already has a checkpoint loaded for other reasons, hand it over instead of
264
+ loading a second copy:
265
+
266
+ ```python
267
+ router.attach("english", existing_agent) # no duplicate 421M parameters
268
+ router.preload() # builds only what is still missing
269
+ ```
270
+
271
+ Measured on CPU with the demo Space's own workload:
272
+
273
+ | | per request | model loads |
274
+ |---|---|---|
275
+ | `Router()` — lazy, `max_loaded=1` | 4–6 s on every language switch | 1 per switch |
276
+ | `Router(preload=True)` | **193–464 ms** | **none** |
277
+
249
278
  ### Memory
250
279
 
251
- All three together are ~1.16B parameters, so `Router` keeps **one** resident by default and
252
- evicts least-recently-used:
280
+ All three together are ~1.16B parameters (~4.6 GB fp32), so `Router` keeps **one** resident by
281
+ default and evicts least-recently-used. Raise it when you have the RAM:
253
282
 
254
283
  ```python
255
284
  Router(max_loaded=2) # keep two hot
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "laya"
7
- version = "0.3.2"
7
+ version = "0.3.3"
8
8
  description = "Fast, non-autoregressive System 1 decision engine with calibrated probabilities"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="laya",
5
- version="0.3.2",
5
+ version="0.3.3",
6
6
  description="Fast, non-autoregressive System 1 decision engine with calibrated probabilities",
7
7
  long_description=open("README.md").read(),
8
8
  long_description_content_type="text/markdown",
@@ -255,6 +255,21 @@ _load_stub(rp2, "english")
255
255
  check("preload/touch does not evict", sorted(rp2.loaded), ["english", "multilingual"])
256
256
 
257
257
 
258
+ # --------------------------------------------------------------------- attach
259
+ ra = stubbed_router(1)
260
+ sentinel = _Stub("already-built")
261
+ ra.attach("english", sentinel)
262
+ check("attach/registers under the name", ra._agents["english"], sentinel)
263
+ check("attach/counts as resident", "english" in ra.loaded, True)
264
+ check("attach/raises max_loaded to hold it", ra.max_loaded >= 1, True)
265
+ # attaching then loading another must not evict the attached one
266
+ ra.max_loaded = max(ra.max_loaded, 2)
267
+ _load_stub(ra, "multilingual")
268
+ check("attach/survives a later load", sorted(ra.loaded), ["english", "multilingual"])
269
+ check("attach/still the same object", ra._agents["english"] is sentinel, True)
270
+ check("attach/accepts aliases", stubbed_router(1).attach("en", _Stub("x")) is not None, True)
271
+
272
+
258
273
  # --------------------------------------------------------------------- report
259
274
  print("\n%d passed, %d failed" % (len(PASS), len(FAIL)))
260
275
  for f in FAIL:
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes