pub const BLOCKED_PREFIXES: &[&str] = &[
"nvidia",
"cuda",
"cudnn",
"cublas",
"cufft",
"curand",
"cusolver",
"cusparse",
"cusparselt",
"nccl",
"nvtx",
"nvjitlink",
"nv-pic",
"tensorrt",
"triton",
"pytorch-cuda",
"torch-cuda",
];
pub const BLOCKED_EXACT: &[&str] = &[
"torch",
"torchvision",
"torchaudio",
"xformers",
"flash-attn",
"flash_attn",
];
pub const CUDA_URL_MARKERS: &[&str] = &[
"+cu1", "+cu2", "+cu3", "+cu4", "cu118", "cu121", "cu124", "cu126", "cu128", "cu129",
];
pub fn extract_pkg_name(requirement: &str) -> &str {
let req = requirement.trim();
let after_marker = req.split(';').next().unwrap_or(req);
let after_extras = after_marker.split('[').next().unwrap_or(after_marker);
after_extras
.split(&['=', '<', '>', '~', '!', ' ', '\t'][..])
.next()
.unwrap_or(after_extras)
.trim()
}
pub fn is_cuda_nvidia_package(requirement: &str) -> bool {
let pkg = extract_pkg_name(requirement).to_lowercase();
if pkg.is_empty() {
return false;
}
if BLOCKED_EXACT
.iter()
.any(|exact| exact.eq_ignore_ascii_case(&pkg))
{
return true;
}
if BLOCKED_PREFIXES
.iter()
.any(|prefix| pkg.starts_with(prefix))
{
return true;
}
if pkg.contains("cuda") {
return true;
}
false
}
pub fn is_cuda_wheel_url(url: &str) -> bool {
let lower = url.to_lowercase();
if CUDA_URL_MARKERS.iter().any(|marker| lower.contains(marker))
|| (lower.contains("+cu") && lower.contains(".whl"))
{
return true;
}
if lower.contains("http://") || lower.contains("https://") || lower.contains(".whl") {
if let Some(pkg) = extract_pkg_name_from_url_filename(&lower) {
if is_nvidia_cuda_runtime_package(&pkg) {
return true;
}
}
}
false
}
fn extract_pkg_name_from_url_filename(url_lower: &str) -> Option<String> {
let filename = url_lower.rsplit(['/', '\\']).next()?;
let filename = filename.trim();
if filename.is_empty() {
return None;
}
let stem = filename.strip_suffix(".whl").unwrap_or(filename);
let mut name_parts: Vec<&str> = Vec::new();
for seg in stem.split('-') {
if seg.is_empty() {
continue;
}
if seg.as_bytes().first().is_some_and(|b| b.is_ascii_digit()) {
break;
}
name_parts.push(seg);
}
if name_parts.is_empty() {
return None;
}
Some(name_parts.join("-"))
}
pub const NVIDIA_RUNTIME_PREFIXES: &[&str] = &[
"nvidia",
"cuda",
"cudnn",
"cublas",
"cufft",
"curand",
"cusolver",
"cusparse",
"cusparselt",
"nccl",
"nvtx",
"nvjitlink",
"nv-pic",
"tensorrt",
"pytorch-cuda",
"torch-cuda",
];
pub fn is_nvidia_cuda_runtime_package(requirement: &str) -> bool {
let pkg = extract_pkg_name(requirement).to_lowercase();
if pkg.is_empty() {
return false;
}
if NVIDIA_RUNTIME_PREFIXES
.iter()
.any(|prefix| pkg.starts_with(prefix))
{
return true;
}
if pkg.contains("cuda") {
return true;
}
false
}
fn is_cuda_only_source(line_lower: &str) -> bool {
if line_lower.contains("ik_llama") {
return true;
}
if (line_lower.contains("exllamav3") || line_lower.contains("flash_attn"))
&& (line_lower.contains("+cu") || line_lower.contains("cu1"))
{
return true;
}
false
}
pub fn filter_requirements_file(path: &str) -> std::io::Result<String> {
std::fs::read_to_string(path).map(|c| filter_requirements(&c))
}
pub fn filter_requirements(content: &str) -> String {
let mut kept = Vec::new();
for line in content.lines() {
let trimmed = line.trim();
if trimmed.is_empty() || trimmed.starts_with('#') {
continue;
}
if is_cuda_nvidia_package(trimmed) {
continue;
}
let line_lower = trimmed.to_lowercase();
if line_lower.contains("http://") || line_lower.contains("https://") {
if is_cuda_wheel_url(trimmed) || is_cuda_only_source(&line_lower) {
continue;
}
} else if is_cuda_only_source(&line_lower) {
continue;
}
kept.push(line.to_string());
}
kept.join("\n")
}
pub fn contaminated_packages(pip_list_output: &str) -> Vec<String> {
let mut found = Vec::new();
for line in pip_list_output.lines() {
let name = line.split_whitespace().next().unwrap_or("");
if is_nvidia_cuda_runtime_package(name) || is_cuda_wheel_url(line) {
found.push(line.trim().to_string());
}
}
found
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn nvidia_wheels_are_blocked() {
assert!(is_cuda_nvidia_package("nvidia-cudnn-cu12"));
assert!(is_cuda_nvidia_package("nvidia-cublas-cu12==12.1.3.1"));
assert!(is_cuda_nvidia_package("nccl"));
assert!(is_cuda_nvidia_package("nvjitlink"));
assert!(is_cuda_nvidia_package("cuda-python"));
assert!(is_cuda_nvidia_package("cupy-cuda12x"));
assert!(is_cuda_nvidia_package("tensorrt"));
}
#[test]
fn torch_family_is_blocked() {
assert!(is_cuda_nvidia_package("torch"));
assert!(is_cuda_nvidia_package("torchvision>=0.17"));
assert!(is_cuda_nvidia_package("torchaudio"));
assert!(is_cuda_nvidia_package("triton"));
assert!(is_cuda_nvidia_package("triton-windows==3.5.1"));
assert!(is_cuda_nvidia_package("xformers"));
assert!(is_cuda_nvidia_package("flash-attn"));
}
#[test]
fn safe_amd_packages_pass() {
assert!(!is_cuda_nvidia_package("deepspeed"));
assert!(!is_cuda_nvidia_package("transformers"));
assert!(!is_cuda_nvidia_package("accelerate"));
assert!(!is_cuda_nvidia_package("einops"));
assert!(!is_cuda_nvidia_package("numpy"));
assert!(!is_cuda_nvidia_package("bitsandbytes"));
assert!(!is_cuda_nvidia_package("vllm"));
assert!(!is_cuda_nvidia_package("wandb"));
}
#[test]
fn cuda_wheel_urls_detected() {
assert!(is_cuda_wheel_url(
"https://x/llama_cpp_binaries-0.124.0+cu124-py3.whl"
));
assert!(is_cuda_wheel_url("https://x/torch-2.4.0+cu118.whl"));
assert!(is_cuda_wheel_url("https://x/flash_attn-2.6+cu128.whl"));
assert!(!is_cuda_wheel_url("https://x/torch-2.4.0+rocm624.whl"));
assert!(!is_cuda_wheel_url("https://x/numpy-1.26.whl"));
}
#[test]
fn direct_nvidia_wheel_url_blocked_without_cu_marker() {
assert!(is_cuda_wheel_url(
"https://download.pytorch.org/whl/cu121/nvidia_cublas_cu12-12.1.3.1-cp310-cp310-linux_x86_64.whl"
));
assert!(is_cuda_wheel_url(
"https://example.com/nvidia-cudnn-cu12-8.9.2-cp310-none-manylinux1_x86_64.whl"
));
assert!(is_cuda_wheel_url(
"https://example.com/cuda_runtime-12.1.0-py3-none-any.whl"
));
assert!(!is_cuda_wheel_url(
"https://download.pytorch.org/whl/rocm6.2/torch-2.4.0-cp310-cp310-linux_x86_64.whl"
));
assert!(!is_cuda_wheel_url(
"https://example.com/numpy-1.26.4-cp310-none-any.whl"
));
}
#[test]
fn filter_requirements_strips_banned_lines() {
let reqs = "\
# comment
torch==2.4.0
nvidia-cudnn-cu12
numpy>=1.26
transformers
https://download.pytorch.org/whl/cu121/xformers-0.0.27%2Bcu121.whl
ik_llama_cpp_cuda-0.1.whl
deepspeed
";
let filtered = filter_requirements(reqs);
assert!(!filtered.contains("torch"));
assert!(!filtered.contains("nvidia-cudnn"));
assert!(!filtered.contains("xformers"));
assert!(!filtered.contains("ik_llama"));
assert!(filtered.contains("numpy>=1.26"));
assert!(filtered.contains("transformers"));
assert!(filtered.contains("deepspeed"));
assert!(!filtered.contains("# comment"));
}
#[test]
fn extract_pkg_name_handles_specs() {
assert_eq!(
extract_pkg_name("nvidia-cudnn-cu12==8.9.2.26"),
"nvidia-cudnn-cu12"
);
assert_eq!(
extract_pkg_name("triton-windows [test]>=3.5.1 ; sys_platform == 'win32'"),
"triton-windows"
);
assert_eq!(extract_pkg_name(" torch "), "torch");
}
#[test]
fn contamination_scan_finds_nvidia_runtime_only() {
let pip_list = "\
Package Version
------------- -------
deepspeed 0.14.5
nvidia-cublas-cu12 12.1.3.1
torch 2.4.0
torchvision 0.19.0
triton 3.1.0
numpy 1.26.4
";
let found = contaminated_packages(pip_list);
assert_eq!(found.len(), 1, "only nvidia-cublas flagged: {found:?}");
assert!(found.iter().any(|l| l.starts_with("nvidia-cublas")));
assert!(!found.iter().any(|l| l.contains("torch")));
assert!(!found.iter().any(|l| l.contains("triton")));
assert!(!found.iter().any(|l| l.contains("deepspeed")));
}
}