Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion avise/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__version__ = "0.2.4"
__version__ = "0.2.5"
__app__ = "AVISE"
__description__ = "AI Vulnerability Identification & Security Evaluation framework"
9 changes: 8 additions & 1 deletion avise/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ def main(arguments=None) -> None:
"-a",
help="API Key to use with requests sent to target API (overrides api_key from Connector configuration file).",
)
parser.add_argument(
"--device",
default=None,
choices=[None, "auto", "cpu", "gpu"],
help='Which device to load local models on ("auto", "cpu", or "gpu"). If given, overrides the device setting from SET configuration file.',
)
parser.add_argument("--version", "-V", action="version", version=__version__)
args = parser.parse_args(arguments)

Expand Down Expand Up @@ -231,6 +237,7 @@ def main(arguments=None) -> None:
output_path=args.output,
target=args.target,
api_key=args.api_key,
device=args.device,
)

# Print a small summary to the console
Expand All @@ -243,7 +250,7 @@ def main(arguments=None) -> None:
print(
f" Failed: {report.summary['failed']} ({report.summary['fail_rate']}%)"
)
print(f" Errors: {report.summary['error']}")
print(f" Inconclusive: {report.summary['error']}")

except Exception as e:
logger.error(
Expand Down
24 changes: 17 additions & 7 deletions avise/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,28 @@

# On Windows, ensure triton-windows package is installed
if os.name == "nt":
if importlib.util.find_spec("triton-windows") is None:
logger.info(
"The current Operating System seems to be Windows. We need to install triton-windows Python package to the current environment in order to run required language models."
if importlib.util.find_spec("triton") is None:
logger.warning(
"triton-windows does not appear to be installed. This should have "
"been installed automatically as a dependency on Windows."
)
try:
import pip # noqa: F401
except ImportError:
raise RuntimeError(
"triton-windows is missing and pip is not available in this "
"environment to install it automatically (this is common with "
"'uv tool' or 'pipx' installs). Please reinstall the package, "
"or run: uv tool install <your-package> --with triton-windows"
)
try:
subprocess.check_call(
[sys.executable, "-m", "pip", "install", "triton-windows"]
)
logger.info(
"Successfully installed triton-windows package to the current environment."
)
except Exception as e:
raise RuntimeError(
"Unable to install triton-windows Python package. Cannot run required language models on Windows without it. Try pip install triton-windows"
"Unable to install triton-windows Python package. "
"Try: pip install triton-windows"
) from e


Expand Down Expand Up @@ -107,6 +115,7 @@ def run_test(
output_path: Optional[str] = None,
target: Optional[str] = None,
api_key: Optional[str] = None,
device: Optional[str] = None,
) -> dict:
"""Run the 4-phase pipeline

Expand Down Expand Up @@ -183,6 +192,7 @@ def run_test(
connector_config_path=connector_config_path,
generate_ai_summary=generate_ai_summary,
runs=runs,
device=device,
)

def _build_connector(self, connector_config: dict, evaluation: bool = False) -> Any:
Expand Down
5 changes: 5 additions & 0 deletions avise/pipelines/languagemodel/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ def __init__(self):
self.evaluation_model_name: Optional[str] = None
self.evaluation_model_max_tokens: Optional[int] = None
self.evaluation_model: Optional[EvaluationLanguageModel] = None
self.device: Optional[str] = None

@abstractmethod
def initialize(self, set_config_path: str) -> List[LanguageModelSETCase]:
Expand Down Expand Up @@ -150,6 +151,7 @@ def run(
connector_config_path: Optional[str] = None,
generate_ai_summary: bool = True,
runs: int = 1,
device: Optional[str] = None,
) -> ReportData:
"""Orchestration method that executes the 4-phase pipeline.
This method gets called by the execution engine.
Expand All @@ -175,6 +177,9 @@ def run(
self.set_config_path = set_config_path
self.target_model_name = connector.model

# Store device
self.device = device

try:
# Initialize
sets = self.initialize(set_config_path)
Expand Down
4 changes: 4 additions & 0 deletions avise/sets/languagemodel/multi_turn/deceptive_delight.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ def initialize(self, set_config_path: str) -> List[LanguageModelSETCase]:

set_config = ConfigLoader().load(set_config_path)

if self.device is not None:
set_config["evaluation_model_device"] = str(self.device)
set_config["adversarial_model_device"] = str(self.device)

sets = set_config.get("sets", [])
if not sets:
raise ValueError(
Expand Down
3 changes: 3 additions & 0 deletions avise/sets/languagemodel/multi_turn/red_queen.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ def initialize(self, set_config_path: str) -> List[LanguageModelSETCase]:
logger.info(f"Initializing Security Evaluation Test: {self.name}")

set_config = ConfigLoader().load(set_config_path)
if self.device is not None:
set_config["evaluation_model_device"] = str(self.device)
set_config["adversarial_model_device"] = str(self.device)

sets = set_config.get("sets", [])
if not sets:
Expand Down
2 changes: 2 additions & 0 deletions avise/sets/languagemodel/single_turn/prompt_injection.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ def initialize(self, set_config_path: str) -> List[LanguageModelSETCase]:
logger.info(f"Initializing SET: {self.name}")

config = ConfigLoader().load(set_config_path)
if self.device is not None:
config["evaluation_model_device"] = str(self.device)

self.evaluation_system_prompt = config.get("evaluation_system_prompt")
if self.evaluation_system_prompt and self.evaluation_model_name:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ build-backend = "hatchling.build"

[project]
name = "avise"
version = "0.2.4"
version = "0.2.5"
authors = [
{ name = "Mikko Lempinen", email="mikko.lempinen@oulu.fi" },
{ name = "Joni Kemppainen" },
Expand Down
Loading