Skip to content

Commit 7de416a

Browse files
committed
Minor fixes
1 parent a8d318d commit 7de416a

12 files changed

Lines changed: 53 additions & 44 deletions

File tree

DESIGN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ TROPT's design is guided by two technical principles:
1717

1818
These two principles together address the *accessibility*, *adaptability*, *comparability*, and *extensibility* requirements motivated in the companion paper; this document is the technical complement, focusing on *how* the design realizes them rather than re-arguing *why* they matter.
1919

20-
In the next segment I describe each of the ==four components==, starting from the lower-level model integration, through the loss modules, the optimizers that drive search, and finally the user-supplied inputs and targets. Crucially, one may abstract the internal design of these components, and merely compose attacks by combining different instances of them.
20+
In the next segment I describe each of the **four components**, starting from the lower-level model integration, through the loss modules, the optimizers that drive search, and finally the user-supplied inputs and targets. Crucially, one may abstract the internal design of these components, and merely compose attacks by combining different instances of them.
2121

2222
In the final segment, I describe the glue: the **recipe**—an executable instantiation of all four components—along with the two existing interfaces (Recipe Hub and the config-driven runner) to run end-to-end optimization in the repo.
2323

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818

1919
<p align="center">
2020
<a href="https://pypi.org/project/tropt/"><img src="https://img.shields.io/pypi/v/tropt?logo=python&logoColor=white&color=3776ab" alt="PyPI"></a>
21-
<a href="https://github.com/matanbt/tropt"><img src="https://img.shields.io/github/stars/matanbt/tropt?style=flat&logo=github&color=181717" alt="GitHub stars"></a>
22-
<a href="https://github.com/matanbt/tropt/actions/workflows/test.yml"><img src="https://img.shields.io/github/actions/workflow/status/matanbt/tropt/test.yml?branch=main&label=tests" alt="Tests"></a>
21+
<a href="https://github.com/matanbt/TROPT"><img src="https://img.shields.io/github/stars/matanbt/TROPT?style=flat&logo=github&color=181717" alt="GitHub stars"></a>
22+
<a href="https://github.com/matanbt/TROPT/actions/workflows/test.yml"><img src="https://img.shields.io/github/actions/workflow/status/matanbt/TROPT/test.yml?branch=main&label=tests" alt="Tests"></a>
2323
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-green?style=flat" alt="License"></a>
2424
</p>
2525

@@ -61,7 +61,7 @@ TROPT lets you run an optimization scheme — a _recipe_ — in a single functio
6161
For instance, you can import the GCG jailbreak ([Zou et al., 2023](https://arxiv.org/abs/2307.15043)) and reproduce it on `gemma-3-1b-it` in a few lines:
6262

6363
```python
64-
from tropt.recipe_hub.GCG import gcg__zou2023
64+
from tropt.recipe_hub import gcg__zou2023
6565

6666
result = gcg__zou2023(
6767
model_name="google/gemma-3-1b-it",
@@ -142,6 +142,6 @@ If you find this package useful, please cite our paper as follows:
142142
@misc{tropt2026,
143143
title = {TROPT: An Open Framework for Unifying and Advancing Discrete Text Optimization},
144144
year = {2026},
145-
howpublished = {\url{https://github.com/matanbt/tropt}},
145+
howpublished = {\url{https://github.com/matanbt/TROPT}},
146146
}
147147
```

tropt/common.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class MessageTargets(pydantic.BaseModel):
8686

8787
target_gradient: Optional[Float[Tensor, "n_params"]] = None
8888
"""Target weight-gradient to align with, flattened over the trainable params.
89-
Precompute via ``tropt.loss.gradient_matching.compute_weight_gradient``.
89+
Precompute the target weight-gradient externally and pass it here.
9090
"""
9191

9292
# ── Classifier targets ─────────────────────────────────────────────────
@@ -172,9 +172,8 @@ class Targets(pydantic.BaseModel):
172172
"""Target weight-gradients, one per template (flattened over the trainable params).
173173
174174
Shape: (n_templates, n_params).
175-
Used by: gradient-matching losses. Precompute via
176-
``tropt.loss.gradient_matching.compute_weight_gradient`` and stack/replicate
177-
across templates.
175+
Used by: gradient-matching losses. Precompute the per-template target
176+
weight-gradients externally and stack across templates.
178177
"""
179178

180179
# ── Classifier targets ─────────────────────────────────────────────────

tropt/loss/losses.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ class SteeringActivationLoss(HiddenStateBasedLoss):
468468

469469
targeted_layers: slice = slice(None)
470470
steer_away: bool = False
471-
slc_name: str = SliceKey.INPUT_LAST_TOKEN
471+
slc_name: SliceKey = SliceKey.INPUT_LAST_TOKEN
472472
do_cosine_sim: bool = False
473473
apply_square: bool = False
474474
apply_abs: bool = False

tropt/model/huggingface/base.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -972,10 +972,10 @@ def compute_loss_from_tokens(
972972
matching, whose value is itself a weight-gradient).
973973
974974
Args:
975-
search_batch_size : int
976-
the number of candidate sequences to evaluate in a given batch
977-
inputs_embeds : Tensor, shape = (search_width, seq_len, embd_dim)
978-
the embeddings of the `search_width` candidate sequences to evaluate
975+
candidate_trigger_ids : Tensor, shape = (n_candidates, trigger_seq_len)
976+
candidate trigger token ids to evaluate
977+
loss_func : BaseLoss
978+
the loss to compute for each candidate
979979
keep_message_dim : bool
980980
whether to return the loss per message (shape = (n_templates, n_candidates))
981981
Returns:
@@ -1015,7 +1015,7 @@ def _compute_candidates_loss__batched(
10151015
logger.debug(f"from loss [msg={template_idx}]: {(cand_idx_end - cand_idx)}")
10161016

10171017
# Only enable gradient is it's required by the loss (e.g. for gradient matching losses); mostly false.
1018-
with torch.set_grad_enabled(loss_func.require_gradients):
1018+
with torch.set_grad_enabled(loss_func.require_gradients):
10191019
model_input = input_manager.get_triggered_inputs(
10201020
chosen_template_idx=template_idx,
10211021
trigger_ids=batch_candidate_trigger_ids,

tropt/model/litellm_proxy/lm.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import logging
22
from typing import Dict, List, Optional
33

4-
import litellm
5-
64
from tropt.common import ModelOutput
75
from tropt.model import BaseTokenizer, LMBaseModel, LossTextAccessMixin
86
from tropt.model.openai.encoder import OpenAITokenizer
@@ -134,6 +132,9 @@ def invoke_from_texts(
134132
generation_kwargs["logprobs"] = True
135133
generation_kwargs["top_logprobs"] = _MAX_TOP_LOGPROBS
136134

135+
# Import litellm lazily: optional dependency (`tropt[litellm]`).
136+
import litellm
137+
137138
outputs = litellm.batch_completion(
138139
model=self.model_name,
139140
messages=prompts,

tropt/model/openai/encoder.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
from typing import Annotated, List, Literal, Optional
22

33
import numpy as np
4-
import tiktoken
54
import torch
6-
from openai import OpenAI
75
from tenacity import retry, stop_after_attempt, wait_exponential
86
from transformers import BatchEncoding
97

@@ -31,6 +29,9 @@ class OpenAITokenizer(BaseTokenizer):
3129
A wrapper around OpenAI's tokenizer that mimics the HuggingFace interface.
3230
"""
3331
def __init__(self, model_name: str) -> None:
32+
# Import tiktoken lazily: optional dependency (`tropt[openai]`).
33+
import tiktoken
34+
3435
# Get the tokeniser corresponding to a specific model in the OpenAI API
3536
try:
3637
self._encoding = tiktoken.encoding_for_model(model_name)
@@ -158,6 +159,8 @@ def __init__(
158159
base_url: Optional base URL for the OpenAI client. If None, the default OpenAI API URL is used.
159160
"""
160161
# Import openai only when instantiating (optional dependency)
162+
from openai import OpenAI
163+
161164
self._client = OpenAI(api_key=api_key, base_url=base_url)
162165
self.model_name = model_name
163166

tropt/optimizer/gasliteplus_optimizer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ def optimize_trigger(
216216
losses=[losses[i].item() for i in range(self.buffer_size)],
217217
)
218218

219-
trigger_str = tokenizer.decode(buffer.get_best_trigger(), skip_special_tokens=True)
219+
trigger_str = tokenizer.decode_trigger(buffer.get_best_trigger())
220220
self.log(loss=buffer.get_lowest_loss(), trigger_str=trigger_str)
221221

222222
for step in self.track_steps(range(self.num_steps), desc="Optimizing with GASLITE..."):

tropt/optimizer/gcg_optimizer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def optimize_trigger(
118118
# Compute loss on all candidate sequences
119119
losses = self.model.compute_loss_from_tokens(
120120
candidate_trigger_ids, loss_func=self.loss_func
121-
) # shape: (n_templates, n_candidates)
121+
) # shape: (n_candidates,)
122122
current_loss = losses.min().item()
123123
trigger_ids = candidate_trigger_ids[losses.argmin()]
124124
trigger_str = tokenizer.decode_trigger(trigger_ids)

tropt/optimizer/utils/retokenization.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,6 @@ def full_messages_retokenize_filtering(
158158
[triggered_template], add_special_tokens=False
159159
).input_ids[0]
160160

161-
print("old texts:", tokenizer.decode(triggered_template_ids))
162-
print("new texts:", tokenizer.decode(triggered_template_new_ids))
163-
164161
# 3. We want the original to match the (re)tokenization:
165162
if triggered_template_ids != triggered_template_new_ids:
166163
is_curr_trigger_valid = False

0 commit comments

Comments
 (0)