wisent 0.5.9__py3-none-any.whl → 0.5.11__py3-none-any.whl

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.

Potentially problematic release.


This version of wisent might be problematic. Click here for more details.

wisent/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.5.9"
1
+ __version__ = "0.5.11"
@@ -95,6 +95,7 @@ class WisentModel:
95
95
  elif self.device == "cuda":
96
96
  load_kwargs["dtype"] = torch.float16
97
97
  load_kwargs["device_map"] = "auto"
98
+ load_kwargs["attn_implementation"] = "flash_attention_2" # Use flash attention for CUDA
98
99
  else:
99
100
  load_kwargs["dtype"] = torch.float32
100
101
  load_kwargs["device_map"] = None
@@ -336,7 +337,7 @@ class WisentModel:
336
337
  @torch.inference_mode()
337
338
  def generate(
338
339
  self,
339
- inputs: list[list[ChatMessage]],
340
+ inputs: list[list[ChatMessage]] | str,
340
341
  max_new_tokens: int = 128,
341
342
  temperature: float = 0.7,
342
343
  top_p: float = 0.95,
@@ -345,6 +346,7 @@ class WisentModel:
345
346
  use_steering: bool = False,
346
347
  steering_plan: SteeringPlan | None = None,
347
348
  enable_thinking: bool = True,
349
+ prompt_is_formatted: bool = False,
348
350
  **gen_kwargs: Any,
349
351
  ) -> list[str]:
350
352
  """
@@ -352,7 +354,7 @@ class WisentModel:
352
354
 
353
355
  attributes:
354
356
  inputs:
355
- list of chat messages (each a list of {'role','content'} dicts).
357
+ list of chat messages (each a list of {'role','content'} dicts) OR pre-formatted string.
356
358
  max_new_tokens:
357
359
  max tokens to generate (beyond the prompt).
358
360
  temperature:
@@ -370,6 +372,8 @@ class WisentModel:
370
372
  If None, uses the internal plan.
371
373
  enable_thinking:
372
374
  If False, disable thinking/reasoning mode (prevents <think> tags for supported models like Qwen).
375
+ prompt_is_formatted:
376
+ If True, inputs is a pre-formatted string with chat template already applied.
373
377
  **gen_kwargs:
374
378
  additional kwargs passed to 'model.generate()'.
375
379
 
@@ -448,7 +452,22 @@ class WisentModel:
448
452
  if use_steering:
449
453
  self.apply_steering(steering_plan)
450
454
 
451
- batch = self._batch_encode(inputs, add_generation_prompt=True, enable_thinking=enable_thinking)
455
+ if prompt_is_formatted and isinstance(inputs, str):
456
+ # Direct tokenization of pre-formatted prompt
457
+ tokenizer_output = self.tokenizer(
458
+ inputs,
459
+ return_tensors="pt",
460
+ padding=False, # Single prompt, no padding needed
461
+ truncation=True, # Avoid errors on long inputs
462
+ max_length=self.tokenizer.model_max_length # Use model's actual limit
463
+ )
464
+ batch = {
465
+ "input_ids": tokenizer_output["input_ids"],
466
+ "attention_mask": tokenizer_output["attention_mask"]
467
+ }
468
+ else:
469
+ # Current behavior: apply chat template
470
+ batch = self._batch_encode(inputs, add_generation_prompt=True, enable_thinking=enable_thinking)
452
471
 
453
472
  gen_out = self.hf_model.generate(
454
473
  **batch,
@@ -612,7 +631,7 @@ class WisentModel:
612
631
  @torch.inference_mode()
613
632
  def generate_stream(
614
633
  self,
615
- inputs: list[list[ChatMessage]],
634
+ inputs: list[list[ChatMessage]] | str,
616
635
  max_new_tokens: int = 128,
617
636
  temperature: float = 0.7,
618
637
  top_p: float = 0.95,
@@ -622,6 +641,7 @@ class WisentModel:
622
641
  skip_prompt: bool = True,
623
642
  skip_special_tokens: bool = True,
624
643
  enable_thinking: bool = True,
644
+ prompt_is_formatted: bool = False,
625
645
  **gen_kwargs: Any,
626
646
  ) -> Iterable[str]:
627
647
  """
@@ -630,7 +650,8 @@ class WisentModel:
630
650
 
631
651
  attributes:
632
652
  inputs:
633
- list of chat messages (each a list of {'role','content'} dicts). Currently only one conversation is supported.
653
+ list of chat messages (each a list of {'role','content'} dicts) OR pre-formatted string.
654
+ Currently only one conversation is supported.
634
655
  max_new_tokens:
635
656
  max tokens to generate (beyond the prompt).
636
657
  temperature:
@@ -650,6 +671,8 @@ class WisentModel:
650
671
  if True, special tokens are removed from the yielded text.
651
672
  enable_thinking:
652
673
  If False, disable thinking/reasoning mode (prevents <think> tags for supported models like Qwen).
674
+ prompt_is_formatted:
675
+ If True, inputs is a pre-formatted string with chat template already applied.
653
676
  **gen_kwargs:
654
677
  additional kwargs passed to 'model.generate()'.
655
678
 
@@ -657,14 +680,29 @@ class WisentModel:
657
680
  generated text chunks (str), as they become available.
658
681
  """
659
682
 
660
- if len(inputs) != 1:
661
- raise ValueError(
662
- f"generate_stream currently supports exactly one conversation at a time (got {len(inputs)})."
663
- )
664
683
  if use_steering:
665
684
  self.apply_steering(steering_plan)
666
685
 
667
- batch = self._batch_encode(inputs, add_generation_prompt=True, enable_thinking=enable_thinking)
686
+ if prompt_is_formatted and isinstance(inputs, str):
687
+ # Direct tokenization of pre-formatted prompt
688
+ tokenizer_output = self.tokenizer(
689
+ inputs,
690
+ return_tensors="pt",
691
+ padding=False, # Single prompt, no padding needed
692
+ truncation=True, # Avoid errors on long inputs
693
+ max_length=self.tokenizer.model_max_length # Use model's actual limit
694
+ )
695
+ batch = {
696
+ "input_ids": tokenizer_output["input_ids"],
697
+ "attention_mask": tokenizer_output["attention_mask"]
698
+ }
699
+ else:
700
+ # Current behavior: apply chat template
701
+ if not isinstance(inputs, list) or len(inputs) != 1:
702
+ raise ValueError(
703
+ f"generate_stream currently supports exactly one conversation at a time (got {type(inputs)} with {len(inputs) if isinstance(inputs, list) else 'N/A'} items)."
704
+ )
705
+ batch = self._batch_encode(inputs, add_generation_prompt=True, enable_thinking=enable_thinking)
668
706
 
669
707
  streamer = TextIteratorStreamer(
670
708
  self.tokenizer,
@@ -166,17 +166,19 @@ class MultiSteering:
166
166
  max_new_tokens: int = 100,
167
167
  temperature: float = 0.7,
168
168
  top_p: float = 0.9,
169
- enable_thinking: bool = True
169
+ enable_thinking: bool = True,
170
+ prompt_is_formatted: bool = False
170
171
  ) -> Iterable[str]:
171
172
  """Apply the combined steering vector to generate text with streaming.
172
173
 
173
174
  Args:
174
175
  model: WisentModel instance to use for generation
175
- prompt: Input prompt
176
+ prompt: Input prompt (either raw text or pre-formatted with chat template)
176
177
  max_new_tokens: Maximum tokens to generate
177
178
  temperature: Sampling temperature
178
179
  top_p: Top-p sampling parameter
179
180
  enable_thinking: If False, disable thinking/reasoning mode (prevents <think> tags for supported models like Qwen)
181
+ prompt_is_formatted: If True, prompt already has chat template applied
180
182
 
181
183
  Yields:
182
184
  Generated text chunks
@@ -191,7 +193,8 @@ class MultiSteering:
191
193
  raise MultiSteeringError("No layer information available")
192
194
 
193
195
  print(f"\n🎯 Applying combined steering vector at layer {self.layer}")
194
- print(f"Prompt: {prompt}")
196
+ print(f"Prompt: {prompt[:100]}..." if len(prompt) > 100 else f"Prompt: {prompt}")
197
+ print(f"Prompt is formatted: {prompt_is_formatted}")
195
198
  print("=" * 50)
196
199
 
197
200
  # Create SteeringPlan from the combined vector
@@ -202,13 +205,19 @@ class MultiSteering:
202
205
  normalize=False # Already normalized in combine_vectors
203
206
  )
204
207
 
205
- # Format prompt as chat messages
206
- messages: list[ChatMessage] = [{"role": "user", "content": prompt}]
208
+ # Handle prompt formatting
209
+ if prompt_is_formatted:
210
+ # Prompt already has chat template applied - pass as string directly
211
+ inputs = prompt
212
+ else:
213
+ # Format prompt as chat messages (current behavior)
214
+ messages: list[ChatMessage] = [{"role": "user", "content": prompt}]
215
+ inputs = [messages]
207
216
 
208
217
  try:
209
218
  # Use WisentModel's generate_stream with steering
210
219
  yield from model.generate_stream(
211
- inputs=[messages],
220
+ inputs=inputs,
212
221
  max_new_tokens=max_new_tokens,
213
222
  temperature=temperature,
214
223
  top_p=top_p,
@@ -216,7 +225,8 @@ class MultiSteering:
216
225
  steering_plan=steering_plan,
217
226
  skip_prompt=True,
218
227
  skip_special_tokens=True,
219
- enable_thinking=enable_thinking
228
+ enable_thinking=enable_thinking,
229
+ prompt_is_formatted=prompt_is_formatted
220
230
  )
221
231
 
222
232
  except Exception as e:
@@ -231,17 +241,19 @@ class MultiSteering:
231
241
  max_new_tokens: int = 100,
232
242
  temperature: float = 0.7,
233
243
  top_p: float = 0.9,
234
- enable_thinking: bool = True
244
+ enable_thinking: bool = True,
245
+ prompt_is_formatted: bool = False
235
246
  ) -> str:
236
247
  """Apply the combined steering vector to generate text (non-streaming).
237
248
 
238
249
  Args:
239
250
  model: WisentModel instance to use for generation
240
- prompt: Input prompt
251
+ prompt: Input prompt (either raw text or pre-formatted with chat template)
241
252
  max_new_tokens: Maximum tokens to generate
242
253
  temperature: Sampling temperature
243
254
  top_p: Top-p sampling parameter
244
255
  enable_thinking: If False, disable thinking/reasoning mode (prevents <think> tags for supported models like Qwen)
256
+ prompt_is_formatted: If True, prompt already has chat template applied
245
257
 
246
258
  Returns:
247
259
  Generated text
@@ -256,7 +268,8 @@ class MultiSteering:
256
268
  raise MultiSteeringError("No layer information available")
257
269
 
258
270
  print(f"\n🎯 Applying combined steering vector at layer {self.layer}")
259
- print(f"Prompt: {prompt}")
271
+ print(f"Prompt: {prompt[:100]}..." if len(prompt) > 100 else f"Prompt: {prompt}")
272
+ print(f"Prompt is formatted: {prompt_is_formatted}")
260
273
  print("=" * 50)
261
274
 
262
275
  # Create SteeringPlan from the combined vector
@@ -267,19 +280,26 @@ class MultiSteering:
267
280
  normalize=False # Already normalized in combine_vectors
268
281
  )
269
282
 
270
- # Format prompt as chat messages
271
- messages: list[ChatMessage] = [{"role": "user", "content": prompt}]
283
+ # Handle prompt formatting
284
+ if prompt_is_formatted:
285
+ # Prompt already has chat template applied - pass as string directly
286
+ inputs = prompt
287
+ else:
288
+ # Format prompt as chat messages (current behavior)
289
+ messages: list[ChatMessage] = [{"role": "user", "content": prompt}]
290
+ inputs = [messages]
272
291
 
273
292
  try:
274
293
  # Use WisentModel's generate with steering
275
294
  outputs = model.generate(
276
- inputs=[messages],
295
+ inputs=inputs,
277
296
  max_new_tokens=max_new_tokens,
278
297
  temperature=temperature,
279
298
  top_p=top_p,
280
299
  use_steering=True,
281
300
  steering_plan=steering_plan,
282
- enable_thinking=enable_thinking
301
+ enable_thinking=enable_thinking,
302
+ prompt_is_formatted=prompt_is_formatted
283
303
  )
284
304
 
285
305
  return outputs[0] if outputs else ""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wisent
3
- Version: 0.5.9
3
+ Version: 0.5.11
4
4
  Summary: Monitor and guard against harmful content in language models
5
5
  Home-page: https://github.com/yourusername/wisent-activation-guardrails
6
6
  Author: Wisent Team
@@ -1,4 +1,4 @@
1
- wisent/__init__.py,sha256=JXLyhF5WmLgRZBfWGz9zWe2g5ISKSLpn2jp8yLaC-s4,22
1
+ wisent/__init__.py,sha256=xFez9dUQrcuZqZRWuEIsCbMskoR-Ke1_uUZ51Kyt1tw,23
2
2
  wisent/benchmarks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  wisent/benchmarks/coding/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  wisent/benchmarks/coding/metrics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -64,7 +64,7 @@ wisent/core/managed_cached_benchmarks.py,sha256=JbvpZ1fgSuQQhyQVKEvqrQZRHGqfnjo9
64
64
  wisent/core/mixed_benchmark_sampler.py,sha256=tKQCHUXVuYeCyx4VZt8O1hGyB-TOY_SQ_SYi8cyApII,13585
65
65
  wisent/core/model_config_manager.py,sha256=rQAdSmk3GFlZXyHp3fSV1bORxiZWhmzIz1uo3H4JtkA,12009
66
66
  wisent/core/model_persistence.py,sha256=6_vc1Ndujd4v0O68giINSTvYhmb7-AiacWwAbqLOrls,10636
67
- wisent/core/multi_steering.py,sha256=EMaKn4dZPlAsFupEUQZlxTZGJ0-ofpLcTCKQk8HaZL8,12295
67
+ wisent/core/multi_steering.py,sha256=YhVKmf08KacVEYZWLk6t2uNWSv-Pi_zBeLdDopo3QXk,13491
68
68
  wisent/core/parser.py,sha256=_YDeSuQMx0zNknz9rX3Ls1YPT1x5eohoY8rfjeoqxV8,69091
69
69
  wisent/core/representation.py,sha256=hBl_N9qbr5Gsa7GCQ0nMWRm82RqYEfhd9cyf0PPH5LY,195
70
70
  wisent/core/sample_size_optimizer.py,sha256=6wegGXZpdGpiR4R0YJ1D2JqLr6yinMndEx2gB5FL80s,23666
@@ -134,7 +134,7 @@ wisent/core/evaluators/oracles/interactive.py,sha256=f3v2_N17fKzGyeOxONRJbrbn8i5
134
134
  wisent/core/evaluators/oracles/nlp_evaluator.py,sha256=KxbnF-I2IFbBQpoYyjQKGbYh4NErsEuhTCRYX_Tob8o,18220
135
135
  wisent/core/evaluators/oracles/user_specified.py,sha256=V1dKrNj3Oq7UC_I7DT0WGnktP7R_DSW6UAwDdrA8SnE,2360
136
136
  wisent/core/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
137
- wisent/core/models/wisent_model.py,sha256=_NDi4oHZnwtUbusqPw8vw1_YYifbsRnD_g25M2uCf08,29772
137
+ wisent/core/models/wisent_model.py,sha256=_XQpakCPJGdzeeSd0gPxp0yd057HisA69uAaW-katDo,31788
138
138
  wisent/core/models/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
139
139
  wisent/core/models/core/atoms.py,sha256=_Bpz0Sfiq6_VswThIltUwNGj_ukl5MhAg8RrgMKwEBM,15756
140
140
  wisent/core/optuna/__init__.py,sha256=sTfwRnrRyKrCNVsF_qCjBDFEZC0ZmUZ7m6IE0iHfTVs,1914
@@ -213,8 +213,8 @@ wisent/synthetic/generators/diversities/core/__init__.py,sha256=47DEQpj8HBSa-_TI
213
213
  wisent/synthetic/generators/diversities/core/core.py,sha256=TjSj5T7NE5kRH-ABcFqb1Hz_j3Z6F_TcV-95uHD5Xw8,2201
214
214
  wisent/synthetic/generators/diversities/methods/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
215
215
  wisent/synthetic/generators/diversities/methods/fast_diversity.py,sha256=Z2UzTbzyJFM_ToxCoXM_LQQQ1Jc6BZknrbpikTG1MRw,8522
216
- wisent-0.5.9.dist-info/licenses/LICENSE,sha256=wy0iaw8b2tyqZAfKHib3lP3PJ9o88FDCg92oUHh3sDQ,1073
217
- wisent-0.5.9.dist-info/METADATA,sha256=lAomuCOIdAio3ai9_IunQG9hytR1WWJ3UjtiScFw9kc,2424
218
- wisent-0.5.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
219
- wisent-0.5.9.dist-info/top_level.txt,sha256=2Ts9Iyldnb3auIN2HBBaHPknRy7nSRDm2f6RGzYgr8A,7
220
- wisent-0.5.9.dist-info/RECORD,,
216
+ wisent-0.5.11.dist-info/licenses/LICENSE,sha256=wy0iaw8b2tyqZAfKHib3lP3PJ9o88FDCg92oUHh3sDQ,1073
217
+ wisent-0.5.11.dist-info/METADATA,sha256=na_FE2Pdt5j8nixhi8wFTOJYLzWweXPgylqL_3Pklx4,2425
218
+ wisent-0.5.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
219
+ wisent-0.5.11.dist-info/top_level.txt,sha256=2Ts9Iyldnb3auIN2HBBaHPknRy7nSRDm2f6RGzYgr8A,7
220
+ wisent-0.5.11.dist-info/RECORD,,