Skip to main content

csim-ai

Neural-augmented Python code plagiarism detection for programming judges. Successor to csim (ANTLR4 parse-tree normalization + Tree Edit Distance), adding a contrastively fine-tuned bi-encoder for the structural/semantic plagiarism cases where pure TED similarity degrades. Scores are a fusion of both signals via a small GBDT, verified to beat Dolos on this project's own test data -- see docs/REPORT.md for the full methodology and results, docs/DEVELOPMENT.md for the phase-by-phase build log.

Task: plagiarism detection (did B derive from A?), not semantic clone detection (does B solve the same problem as A?). Two independent correct solutions to the same problem are a negative, not a positive.

Install

pip install csim-ai              # bi-encoder cosine similarity only (onnxruntime, no torch)
pip install csim-ai[ast,scorer]  # + csim TED signal + GBDT fusion -- the full hybrid score

Model weights aren't bundled in the package (the ONNX export is ~500MB) -- run csim-ai setup once after installing to download and cache them from Hugging Face Hub (edson-eddy/csim-ai). After that, both the CLI and the Scorer class auto-detect the cache and give the full hybrid score with no further flags or arguments.

pip install csim-ai[ast,scorer]
csim-ai setup
# bi-encoder cached at: ~/.cache/huggingface/hub/models--edson-eddy--csim-ai/...
# fusion model cached at: .../fusion_model.joblib

CLI

CLI shape follows csim's, not a from-scratch design: a single csim-ai command, an action positional, --path pointing at a directory compared exhaustively -- same pattern as csim {report,group,tree,view,info} --path DIR --lang ... --talg ..., since this tool has the same predecessor and audience.

csim-ai report --path submissions/
# b.py is similar to a.py with similarity index: 0.9998 (biencoder_cosine=1.0000, csim_ted=1.0000, fusion=0.9998)

csim-ai group --path submissions/ --threshold 0.9
# Group 1 (Average Similarity: 1.00):
# a.py
# c.py
# Unique Files (similarity below threshold):
# b.py

csim-ai info
# which optional backends (onnxruntime, tokenizers, huggingface_hub, csim, scikit-learn, torch) are available

report

Pairwise similarity report over every .py file in --path, all combinations.

Flag Default Meaning
--path, -p required Directory of .py files to compare exhaustively.
--model-path Hugging Face Hub Directory with model.onnx/tokenizer.json. Skips the Hub entirely if given.
--fusion-model none Path to a fusion_model.joblib. Skips the Hub entirely if given.
--use-fusion off Force-download the fusion model from HF Hub if it isn't already cached and no --fusion-model is given.

group

Same comparison as report, but groups files into connected components by a similarity threshold instead of listing every pair.

Same flags as report, plus:

Flag Default Meaning
--threshold, -t required Similarity threshold (0.0-1.0) for grouping.

info

No comparison -- just reports which optional backends are importable (onnxruntime/tokenizers/huggingface_hub from the base install; csim/scikit-learn from [ast,scorer]; torch from [export]). Takes an optional --model-path to also check a directory for model.onnx/tokenizer.json.

setup

Not part of pip install . -- a separate step because the weights aren't bundled in the package.

Flag Default Meaning
(none) -- Downloads and caches the bi-encoder + fusion model from Hugging Face Hub.
--export-from CHECKPOINT none Export a local torch checkpoint to ONNX instead of downloading (requires pip install csim-ai[export]) -- entirely offline, for your own fine-tuned weights rather than this project's.
--out ./onnx_model Output directory for --export-from.
--opset 17 ONNX opset version for --export-from.
--no-verify off Skip the PyTorch-vs-ONNX parity check after --export-from.

GPU (optional)

report/group accept --device {cpu,cuda,auto} (default cpu -- nothing changes unless you ask). The bi-encoder is the dominant runtime cost by far -- on one real 29-file/406-pair directory (RTX 3060 Ti):

Device Time Result
cpu (default) 7.7s 5 groups
cuda 4.2s same 5 groups

GPU isn't automatic because the base install's onnxruntime is CPU-only, and onnxruntime-gpu occupies the exact same import name -- they can't both be installed. To use it:

pip uninstall onnxruntime
pip install onnxruntime-gpu

...plus the CUDA/cuDNN runtime libraries (a system CUDA toolkit, or the nvidia-cublas-cuXX/nvidia-cudnn-cuXX pip packages -- already present if torch's CUDA build happens to be installed in the same environment). Requesting --device cuda without a working CUDAExecutionProvider doesn't fail -- onnxruntime silently falls back to CPU -- so csim-ai checks and prints a warning to stderr when that happens, instead of leaving it silent. --device auto requests CUDA the same way but stays quiet if it isn't available (falls back to CPU without complaint). csim-ai info shows which execution providers onnxruntime actually has available.

For every report/group result, "similarity index" is the fusion score when available, else biencoder_cosine. csim_ted/ fusion come back as None (and are dropped from the report line) when csim/scikit-learn aren't installed, so a bare pip install csim-ai (no extras, no setup) still gives a usable bi-encoder-only score.

Python API

from csim_ai import Scorer

scorer = Scorer()                     # after `csim-ai setup`: full hybrid, cache auto-detected
scorer = Scorer(use_fusion=True)      # force-downloads the fusion model too if `setup` wasn't run yet
scorer = Scorer(
    "path/to/onnx_model",
    fusion_model_path="path/to/fusion_model.joblib",
)                                      # fully local, no network

scorer.score(code_a, code_b)
# {"biencoder_cosine": 0.987, "csim_ted": 0.83, "fusion": 0.978}

Scorer(model_path=None, fusion_model_path=None, use_fusion=False, device="cpu"):

  • model_path: directory with model.onnx/tokenizer.json. None (default) downloads from Hugging Face Hub, cached after first call.
  • fusion_model_path: path to a fusion_model.joblib. None (default) auto-uses a fusion model already cached by a prior csim-ai setup or use_fusion=True call, without triggering a network request to check.
  • use_fusion: if True and no fusion_model_path is given, force-downloads the fusion model from HF Hub instead of just checking the cache.
  • device: "cpu" (default, matches the base install exactly), "cuda", or "auto" -- see GPU section above. "cuda"/"auto" need onnxruntime-gpu in place of plain onnxruntime.

scorer.score(code_a: str, code_b: str) -> dict returns {"biencoder_cosine": float, "csim_ted": float | None, "fusion": float | None} -- csim_ted/fusion are None when csim/scikit-learn aren't installed or no fusion model is available.

Layout

src/csim_ai/       inference package -- ONNX bi-encoder + csim TED + GBDT fusion
tests/             pytest smoke tests for src/csim_ai
training/          dataset prep, synthetic plagiarism generation, training, eval, export tooling
docs/
  REPORT.md        project narrative: problem, methodology, results, limitations
  DEVELOPMENT.md   phase-by-phase build log: commands, exact numbers, bugs hit and fixed

Release files for csim-ai 0.0.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for csim-ai 0.0.4
File Size Uploaded
csim_ai-0.0.4.tar.gz 14.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for csim-ai 0.0.4
File Interpreter ABI Platform
csim_ai-0.0.4-py3-none-any.whl Python 3 none any Details

Total release size: 31.1 kB

Release files / csim_ai-0.0.4.tar.gz

Download URL csim_ai-0.0.4.tar.gz
Size 14.7 kB
Tags Source
SHA-256 checksum
How to use checksums
1c3e2135b62560fafb55804c8b18f07aef6d6db357352d0750c264ee3df54d4a
BLAKE2b-256 checksum
How to use checksums
2ae58683a1d7c930f05b33ce323ad697d14306ee16cc6fde55819c10aa8e962e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release files / csim_ai-0.0.4-py3-none-any.whl

Download URL csim_ai-0.0.4-py3-none-any.whl
Size 16.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2bc8fdc39f1ccae96ea5c22ac5b66167df1230bdcbd8faee7bd1006b1aa9ad0a
BLAKE2b-256 checksum
How to use checksums
36f026fbddda027cb45130a2fb620e36ef15aea1d89d23871723bc556c14de9d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release history Release notifications | RSS feed

This release

0.0.4 This release

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page