Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
123 commits
Select commit Hold shift + click to select a range
3a87452
[demo] Experimental LoRA model save/load: save base model and LoRA ad…
k-arima-3150 Apr 15, 2026
20865fb
[update] add save/load support to JointQ based on _gptq.py
S4Y-K Apr 16, 2026
23f4a6e
[update] Add script for training a LoRA model with OneCompression kno…
cm-ysmz Apr 17, 2026
2a0cf1c
Merge branch 'Branch_20865fb7' into feature/ysmz/lora-save-load-vllm-…
cm-ysmz Apr 20, 2026
d556d97
[update] Add script for training a JointQ+LoRA model with OneCompress…
cm-ysmz Apr 21, 2026
71cd666
[fix] add missing commit
cm-ysmz Apr 22, 2026
8aa8291
[refactor] revised comments and renamed methods
cm-ysmz Apr 22, 2026
4caf856
Merge pull request #11 from FujitsuResearch/develop/v1-1-0
FKKimura Apr 28, 2026
c65d7e2
Define v1.1.1
FKKimura May 7, 2026
9775761
[fix] support load of unpacked JointQ wbits=1 checkpoints
S4Y-K Apr 27, 2026
ad353f4
Merge remote-tracking branch 'remotes/origin/cm/dev' into verify/ysmz…
cm-ysmz May 8, 2026
764b98a
feat: log quantization progress with linear ETA
sotanengel May 13, 2026
ce8232d
[update] Add script for training a LoRA model with OneCompression kno…
cm-ysmz May 14, 2026
27566cf
[refactor] Delete working files
cm-ysmz May 14, 2026
3ec1166
[update] Update CHANGELOG.md (LoRA Adapter Sidecar Save/Load)
cm-ysmz May 14, 2026
7517c18
Raise clear error for unsupported QEP quantizers
FKKimura May 18, 2026
a946fa7
Merge branch 'lab/fix-jointq-qep' into 'export/v1-1-1'
FKKimura May 18, 2026
2cb598c
Merge pull request #13 from sotanengel/feature/quantization-progress-eta
FKKimura May 19, 2026
1470e5c
Refactoring: quantization progress logs with ETA (#15)
aki916f May 19, 2026
c1bc4b7
refactor(progress): tidy [progress] logs and harden tracker
FKKimura May 19, 2026
564ccfe
Merge branch 'lab/quantization_progress' into 'export/v1-1-1'
FKKimura May 19, 2026
514371c
fix(vlm): save aux files, load with correct dtype, retie tied embeddings
FKKimura May 20, 2026
c510cfe
Merge branch 'lab/issue-64-takane-vision' into 'export/v1-1-1'
FKKimura May 20, 2026
5a6d5fe
Fix tests and examples
FKKimura May 20, 2026
3a119e6
Merge branch 'lab/fix-tests-examples' into 'export/v1-1-1'
FKKimura May 20, 2026
9d97d43
Apply black
FKKimura May 20, 2026
9e784d0
Trivial-fix
FKKimura May 21, 2026
b82753b
Merge pull request #20 from FujitsuResearch/develop/v1-1-1
FKKimura May 21, 2026
0db87e6
Define v1.2.0
FKKimura May 21, 2026
7122b42
Merge branch 'cm/dev' into feature/ysmz/lora-save-load-vllm-infer_jointq
cm-ysmz May 25, 2026
3564765
Update benchmark (v1.1.1)
FKKimura May 25, 2026
bc7ac62
[fix] raise ValueError when LoRA sidecar adapters are only partially …
cm-ysmz May 25, 2026
815fd5c
Add pre-commit hooks for local development
aki916f May 25, 2026
b739b2c
Merge branch 'lab/precommit' into 'export/v1-2-0'
aki916f May 25, 2026
a510a24
[fix] resolve LoRA adapter layers by suffix when module prefixes differ
cm-ysmz May 26, 2026
0cf14bf
[chore] rename files
cm-ysmz May 26, 2026
9f5c98a
[chore] rename files
cm-ysmz May 26, 2026
49dbec4
[refactor] improve ValueError for LoRA sidecar apply failures
cm-ysmz May 26, 2026
91d4f2f
[update] Update CHANGELOG.md (v1.1.1 merge and fixes/file renames)
cm-ysmz May 26, 2026
a26e8e3
[style(onecomp)] run black formatter
k-arima-3150 May 26, 2026
20a7c68
[add] add requirements.txt for legacy-vllm environments (0.12.0/0.15.1)
cm-ysmz May 28, 2026
2f87eed
[fix] Fix requirements.txt and Add README.md (0.12.0/0.15.1)
cm-ysmz May 28, 2026
39e64e1
[fix] correctiong spelling mistakes in commands
cm-ysmz May 28, 2026
310a799
[update] Update CHANGELOG.md (legacy vllm environment)
cm-ysmz May 28, 2026
6a4496e
fix: quantizer unit test fixes and tighten GPTQ thresholds (#21)
k-arima-3150 Jun 3, 2026
b4920c3
feat: add save/load support for JointQ, RTN, and OneBit quantizers (#22)
k-arima-3150 Jun 3, 2026
ba66b76
add dashboard
aki916f Jun 4, 2026
41df7fe
Merge branch 'lab/dashboard' into 'export/v1-2-0'
aki916f Jun 4, 2026
cce8157
Merge branch 'lab/benchmark-v1-1-1' into 'export/v1-2-0'
FKKimura Jun 4, 2026
8ef90ad
Add MPS (Apple Silicon) device support (#7)
aki916 Jun 5, 2026
ee47ac9
add mt-bench and throughput evaluator
aki916f Jun 5, 2026
4fc6da2
Merge branch 'lab/mt-bench' into 'export/v1-2-0'
aki916f Jun 5, 2026
bbb8406
Add global ptq
yishii836 Jun 8, 2026
7731494
Merge branch 'lab/issue-39-global-ptq' into 'export/v1-2-0'
FKKimura Jun 8, 2026
8954b36
Do not install vllm 0.22.0 due to unsupporting exllama kernel
aki916f Jun 8, 2026
8d6a6ad
Merge branch 'lab/vllm_version' into 'export/v1-2-0'
FKKimura Jun 8, 2026
ada74d1
Merge branch 'develop/v1-2-0' into export/v1-2-0
FKKimura Jun 8, 2026
69c6c56
Apply isort and black
FKKimura Jun 8, 2026
2564db0
Update uv.lock
FKKimura Jun 8, 2026
d05d875
Modify pyproject.toml and uv.lock
FKKimura Jun 8, 2026
dcf6620
update README in dashboard
aki916f Jun 8, 2026
d9e12cc
Update docstring in examples
FKKimura Jun 8, 2026
36e6873
Bug-fix GlobalPTQDistributed to save a quantized model
FKKimura Jun 8, 2026
fe80ff9
Fix eval and dashboard for FujitsuResearch/OneCompressionn PR 23
FKKimura Jun 8, 2026
8654af0
Merge branch 'hotfix/github-pr-23' into 'export/v1-2-0'
FKKimura Jun 8, 2026
94e77ed
prevent file traversal based on input model_id (dashboard)
aki916f Jun 9, 2026
b9a7172
Merge branch 'hotfix/dashboard_path' into 'export/v1-2-0'
FKKimura Jun 9, 2026
6e83766
Merge pull request #23 from FujitsuResearch/develop/v1-2-0
FKKimura Jun 9, 2026
6ac4d07
Define v1.3.0
FKKimura Jun 9, 2026
e7e295c
Define v1.3.0
FKKimura Jun 9, 2026
3a09bf9
[fix] derive Hadamard hook target types from model instead of quant_m…
KoOhira-BP Jun 9, 2026
886fc4b
[fix]collect all down_proj types for Hadamard hooks instead of sampli…
KoOhira-BP Jun 9, 2026
0602f90
Merge remote-tracking branch 'upstream/develop/v1-3-0' into feature/y…
k-arima-3150 Jun 9, 2026
007e396
Merge remote-tracking branch 'upstream/develop/v1-3-0' into feature/y…
k-arima-3150 Jun 9, 2026
fe49076
[style] Apply pre-commit fixes
k-arima-3150 Jun 9, 2026
302cc39
[style] Apply pre-commit fixes and tidy example params/comments
k-arima-3150 Jun 10, 2026
6ef7dc5
[fix] fix LoRA SFT usage paths and changelog wording
cm-ysmz Jun 10, 2026
a4e920f
Merge remote-tracking branch 'upstream/develop/v1-3-0' into feature/y…
k-arima-3150 Jun 10, 2026
53fb66f
[fix] Restore accidentally dropped enable_lora/max_lora_rank in vLLM …
k-arima-3150 Jun 10, 2026
ba5c2fe
[fix] Discover all down_proj layer types for Hadamard hook registrati…
KoOhira-BP Jun 11, 2026
f4985f8
[fix] down_proj type collection to exclude Linear;pass use_gemlite=Fa…
KoOhira-BP Jun 12, 2026
8c676a6
[fix] Remove explicit use_gemlite=False in perplexity eval path
KoOhira-BP Jun 15, 2026
23993c8
[fix] Fail fast on ambiguous LoRA target in _resolve_name_by_layer_su…
k-arima-3150 Jun 16, 2026
580fc3e
VLM key unmatch error during quantized model load
aki916f Jun 16, 2026
92acd4a
Merge branch 'lab/vlm_error' into 'export/v1-3-0'
aki916f Jun 16, 2026
ab9aa25
fix: load generation_config.json in load_quantized_model() for Gemma-…
aki916f Jun 16, 2026
54ae95e
Merge branch 'lab/gemma4-12b' into 'export/v1-3-0'
aki916f Jun 16, 2026
ffed032
[fix] Save LoRA adapter sidecar in base model dtype instead of fixed …
k-arima-3150 Jun 16, 2026
4e16eb5
[update] Add in-place pack/unpack utilities to GPTQLinear
cm-ysmz Jun 16, 2026
b350d32
[test] Add regression tests for Hadamard hook target-type collection
KoOhira-BP Jun 16, 2026
6347b3a
[update] Make post-processes (LoRA) preserve the quantized model's pa…
cm-ysmz Jun 16, 2026
89c67b8
[fix] Export LoRA GPTQ models without rebuilding from results
cm-ysmz Jun 16, 2026
b595f85
[fix] fix comments and add LoRA tests
cm-ysmz Jun 16, 2026
c74fbae
[test] Pin down_proj hook-type collection; extract collectors to rota…
k-arima-3150 Jun 17, 2026
b6fffdf
Merge remote-tracking branch 'remotes/upstream/develop/v1-3-0' into f…
cm-ysmz Jun 17, 2026
8d8df95
Merge remote-tracking branch 'remotes/origin/feature/ysmz/lora-save-l…
cm-ysmz Jun 17, 2026
a4e2a12
[fix] fix test. align runner stubs with _collect_lora_gptq_modules an…
cm-ysmz Jun 17, 2026
d3af731
[update] Update CHANGELOG.md (v1.3.0-wip merge and LoRA/GPTQ pack upd…
cm-ysmz Jun 17, 2026
ccd49f1
Merge remote-tracking branch 'upstream/develop/v1-3-0' into fix/koohr…
k-arima-3150 Jun 18, 2026
c2478b0
[style] Apply pre-commit fixes
k-arima-3150 Jun 18, 2026
602e79c
Setup test automation and linter check corresponding to merge request
aki916f Jun 18, 2026
2cbe006
Merge branch 'lab/auto_test' into 'export/v1-3-0'
FKKimura Jun 18, 2026
b2fb676
ci: add SAST and secret detection
FKKimura Jun 18, 2026
f0c9290
Merge branch 'lab/add-sast-secret-detection' into 'export/v1-3-0'
FKKimura Jun 18, 2026
1467311
[doc] Add CHANGELOG entry for partial-quant rotation Hadamard hook ta…
k-arima-3150 Jun 18, 2026
52c0c34
[fix] fix example usage
cm-ysmz Jun 19, 2026
1b9e9a0
Merge remote-tracking branch 'upstream/develop/v1-3-0' into fix/koohr…
k-arima-3150 Jun 19, 2026
b3e51ab
add notebook for youtube
aki916f Jun 19, 2026
9e7a35c
Merge branch 'lab/notebook' into 'export/v1-3-0'
aki916f Jun 19, 2026
9f676ce
[fix] stop forcing GPTQ pack on export when pack_weights=False
cm-ysmz Jun 19, 2026
d60d7a8
Merge remote-tracking branch 'remotes/upstream/develop/v1-3-0' into f…
cm-ysmz Jun 19, 2026
6384b1a
[style] Apply black formatter
cm-ysmz Jun 19, 2026
306177b
[update] Update CHANGELOG.md (v1.3.0-wip merge into LoRA branch)
cm-ysmz Jun 19, 2026
0193645
Merge remote-tracking branch 'upstream/develop/v1-3-0' into fix/koohr…
k-arima-3150 Jun 19, 2026
ae63233
[fix] refine vLLM 0.12.0/0.15.1 setup guide
cm-ysmz Jun 26, 2026
a542924
[fix] Centralize LoRA adapter subdir constant
cm-ysmz Jun 26, 2026
b43bf53
Merge pull request #25 from computermind-corp/feature/legacy-vllm
aki916f Jun 30, 2026
3a831c3
Merge branch 'develop/v1-3-0' into feature/lora-save-load-vllm-infer_…
k-arima-3150 Jun 30, 2026
6e080ec
Merge pull request #27 from computermind-corp/feature/lora-save-load-…
aki916f Jun 30, 2026
1ba31e8
Merge remote-tracking branch 'upstream/develop/v1-3-0' into fix/koohr…
k-arima-3150 Jul 3, 2026
b9039bf
Merge pull request #30 from computermind-corp/fix/partial-quant-with-…
aki916f Jul 3, 2026
34a06e1
Merge branch 'main' into export/v1-3-0
FKKimura Jul 6, 2026
6e10f9c
Merge commit 'b9039bfc2b28a01e11d6671c9e8b19e91b7602e3' into export/v…
FKKimura Jul 6, 2026
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
275 changes: 275 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,278 @@
include:
- template: Jobs/SAST.gitlab-ci.yml
- template: Jobs/Secret-Detection.gitlab-ci.yml

# Run merge request pipelines (lint/test/security + enforcement on the MR), web
# (manual) pipelines, and push pipelines on integration branches (export/*) so the
# SAST baseline keeps being published. Plain feature-branch pushes create no
# pipeline, which also avoids duplicate branch + MR pipelines.
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_PIPELINE_SOURCE == "web"
- if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH =~ /^export\//

stages:
- lint
- test
- security-gate
- deploy

variables:
UV_CACHE_DIR: "${CI_PROJECT_DIR}/.cache/uv"
GIT_DEPTH: "1"
PYTEST_MARKERS: "not slow"

lint:format:
extends: .skip_docs_only
stage: lint
tags:
- lint
cache:
key: lint-uv-cache
paths:
- .cache/uv/
policy: pull-push
before_script:
- export PATH="${HOME}/.local/bin:${PATH}"
script:
- uvx isort@8.0.1 --check-only onecomp/ vllm_plugins/
- uvx black@26.5.1 --check onecomp/ vllm_plugins/

# Skip jobs when the merge request changes docs/markdown only (**/*.md, docs/**).
# GitLab changes has no negated globs, so we whitelist non-doc paths instead.
# Always compare the whole MR diff against the target branch: comparing against
# $CI_COMMIT_BEFORE_SHA breaks when it is the all-zero SHA (first MR pipeline),
# because GitLab validates every rule's compare_to ref at pipeline creation.
.skip_docs_only_paths: &skip_docs_only_paths
- onecomp/**/*
- tests/**/*
- vllm_plugins/**/*
- example/**/*
- scripts/**/*
- pyproject.toml
- uv.lock

.skip_docs_only:
rules:
- if: $CI_PIPELINE_SOURCE == "web"
when: on_success
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
changes:
compare_to: 'refs/heads/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME'
paths: *skip_docs_only_paths
when: on_success
- when: never

.cluster_job:
stage: test
extends: .skip_docs_only
tags:
- cluster
before_script:
- |
for var in \
CI_BASTION_HOST CI_CLUSTER_HOST CI_CLUSTER_USER ONECOMP_REPO \
CI_SLURM_PARTITION CI_SLURM_MEM CI_SLURM_CPUS CI_SLURM_TIME CI_SLURM_GPUS \
CI_UV_VENV CI_TORCH_EXTRA; do
eval "test -n \"\${${var}:-}\" || { echo \"Set ${var} in CI/CD Variables\" >&2; exit 1; }"
done

# Export job env safely (printf %q), then pipe cluster_test.sh to remote bash -s.
# Runner env vars are not forwarded over SSH automatically.
.cluster_ssh:
script:
- |
{
printf 'export ONECOMP_REPO=%q\n' "${ONECOMP_REPO}"
printf 'export CI_COMMIT_SHA=%q\n' "${CI_COMMIT_SHA}"
printf 'export CI_COMMIT_REF_NAME=%q\n' "${CI_COMMIT_REF_NAME:-}"
printf 'export CI_JOB_TOKEN=%q\n' "${CI_JOB_TOKEN}"
printf 'export CI_SERVER_HOST=%q\n' "${CI_SERVER_HOST}"
printf 'export CI_PROJECT_PATH=%q\n' "${CI_PROJECT_PATH}"
printf 'export CLUSTER_MODE=%q\n' "${CLUSTER_MODE:-test}"
printf 'export SKIP_UV_SYNC=%q\n' "${SKIP_UV_SYNC:-0}"
printf 'export JOB_LABEL=%q\n' "${JOB_LABEL:-test}"
printf 'export PYTEST_TARGET=%q\n' "${PYTEST_TARGET:-tests/}"
printf 'export PYTEST_MARKERS=%q\n' "${PYTEST_MARKERS:-}"
printf 'export CI_SLURM_PARTITION=%q\n' "${CI_SLURM_PARTITION}"
printf 'export CI_SLURM_MEM=%q\n' "${CI_SLURM_MEM}"
printf 'export CI_SLURM_CPUS=%q\n' "${CI_SLURM_CPUS}"
printf 'export CI_SLURM_TIME=%q\n' "${CI_SLURM_TIME}"
printf 'export CI_SLURM_GPUS=%q\n' "${CI_SLURM_GPUS}"
printf 'export CI_SLURM_EXCLUDE=%q\n' "${CI_SLURM_EXCLUDE:-}"
printf 'export CI_UV_VENV=%q\n' "${CI_UV_VENV}"
printf 'export CI_TORCH_EXTRA=%q\n' "${CI_TORCH_EXTRA}"
cat scripts/cluster_test.sh
} | ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new \
"${CI_CLUSTER_USER}@${CI_BASTION_HOST}" \
"ssh -o BatchMode=yes ${CI_CLUSTER_USER}@${CI_CLUSTER_HOST} bash -s"

# Lightweight connectivity check only; does not run cluster_test.sh.
test:cluster-smoke:
extends: .cluster_job
script:
- |
ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new \
"${CI_CLUSTER_USER}@${CI_BASTION_HOST}" \
"ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new ${CI_CLUSTER_USER}@${CI_CLUSTER_HOST} bash -s" \
< scripts/cluster_smoke.sh

# One shared env sync (CLUSTER_MODE=setup); pytest shards reuse it via SKIP_UV_SYNC=1.
test:cluster-setup:
extends:
- .cluster_job
- .cluster_ssh
timeout: 3h
variables:
CLUSTER_MODE: setup
JOB_LABEL: setup

test:onecomp:
extends:
- .cluster_job
- .cluster_ssh
needs:
- test:cluster-setup # shards wait for env sync, not for smoke
timeout: 13h
variables:
CLUSTER_MODE: test
SKIP_UV_SYNC: "1"
# One job definition → four parallel pytest jobs (JOB_LABEL + PYTEST_TARGET only).
parallel:
matrix:
- JOB_LABEL: quantizer
PYTEST_TARGET: "tests/onecomp/quantizer/"
- JOB_LABEL: pre-process
PYTEST_TARGET: "tests/onecomp/pre_process/ tests/onecomp/calibration/ tests/onecomp/lpcd/"
- JOB_LABEL: core
PYTEST_TARGET: "tests/onecomp/runner/ tests/onecomp/post_process/ tests/onecomp/utils/ tests/onecomp/test_make_grouped_module.py tests/onecomp/test_runner_check.py tests/onecomp/test_eval_quantized_vs_dequantized.py tests/onecomp/test_qep_general_consistency.py tests/onecomp/test_cumulative_error_regression.py tests/onecomp/test_qep_gptq_regression.py"
- JOB_LABEL: vllm
PYTEST_TARGET: "tests/vllm_plugins/"

# Ensure the security jobs run in merge request pipelines and on export/* pushes
# (the managed templates' default rules are branch-oriented). Overrides only the
# rules; security scans intentionally run regardless of docs-only changes.
.security_rules:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_PIPELINE_SOURCE == "web"
- if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH =~ /^export\//

# Surface analyzer infra errors instead of silently passing.
secret_detection:
allow_failure: false
rules: !reference [.security_rules, rules]

semgrep-sast:
allow_failure: false
rules: !reference [.security_rules, rules]

# Fail the pipeline when secret detection reports any finding.
# The analyzer exits 0 even on findings, so we gate on its report.
secret-detection-gate:
stage: security-gate
rules: !reference [.security_rules, rules]
needs:
- job: secret_detection
artifacts: true
image: alpine:3
before_script:
- apk add --no-cache jq
script:
- test -f gl-secret-detection-report.json || { echo "secret detection report not found"; exit 1; }
- count=$(jq '[.vulnerabilities[]] | length' gl-secret-detection-report.json)
- echo "secret detection findings=$count"
- >
if [ "$count" -gt 0 ]; then
echo "Secrets detected. Failing the pipeline.";
jq -r '.vulnerabilities[] | "- \(.message) (\(.location.file):\(.location.start_line))"' gl-secret-detection-report.json;
exit 1;
fi

# Fail only when this branch introduces NEW High/Critical SAST findings,
# compared with the baseline branch's latest SAST report.
# Signature for matching: severity + semgrep rule id + file (line-shift tolerant).
#
# Baseline ref is resolved dynamically (no hard-coded branch name):
# 1. the merge request target branch (CI_MERGE_REQUEST_TARGET_BRANCH_NAME), else
# 2. an explicit override (SAST_BASELINE_REF), else
# 3. none -> enforcement skipped (report only).
# A direct push build of an integration branch (matching SAST_BASELINE_GLOB,
# e.g. export/*) is informational, so it stays green and keeps publishing a
# baseline report for future merge requests.
sast-gate:
stage: security-gate
rules: !reference [.security_rules, rules]
needs:
- job: semgrep-sast
artifacts: true
image: alpine:3
variables:
# Integration branches (shell glob) that only publish a baseline on push.
SAST_BASELINE_GLOB: "export/*"
# Optional explicit baseline ref for non-MR pipelines (empty = none).
SAST_BASELINE_REF: ""
before_script:
- apk add --no-cache jq curl
script:
- |
set -eu
test -f gl-sast-report.json || { echo "sast report not found"; exit 1; }

SIG='[.vulnerabilities[] | select(.severity=="High" or .severity=="Critical") | (.severity + "|" + ((.identifiers[0].value // "?")|tostring) + "|" + (.location.file // "?"))] | unique'

total=$(jq '[.vulnerabilities[] | select(.severity=="High" or .severity=="Critical")] | length' gl-sast-report.json)
echo "current High/Critical total=${total} (this ref=${CI_COMMIT_REF_NAME})"

# Direct push build of an integration branch (not a merge request):
# only publish the baseline, do not enforce.
case "${CI_COMMIT_REF_NAME}" in
${SAST_BASELINE_GLOB})
if [ -z "${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-}" ]; then
echo "On integration branch ${CI_COMMIT_REF_NAME}; gate is informational. Not failing."
exit 0
fi
;;
esac

BASE_REF="${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-${SAST_BASELINE_REF}}"
if [ -z "${BASE_REF}" ]; then
echo "No baseline ref (not an MR pipeline and SAST_BASELINE_REF unset). Skipping new-only enforcement."
exit 0
fi
echo "baseline ref=${BASE_REF}"

url="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/jobs/artifacts/${BASE_REF}/raw/gl-sast-report.json?job=semgrep-sast"
http=$(curl -s -o baseline.json -w '%{http_code}' --header "JOB-TOKEN: ${CI_JOB_TOKEN}" "${url}" || echo "000")
echo "baseline fetch HTTP=${http}"

if [ "${http}" != "200" ] || ! jq -e . baseline.json >/dev/null 2>&1; then
echo "No usable baseline report on ${BASE_REF} (bootstrap). Skipping new-only enforcement."
exit 0
fi

jq "${SIG}" baseline.json > base_sigs.json
jq --slurpfile base base_sigs.json '
[.vulnerabilities[]
| select(.severity=="High" or .severity=="Critical")
| {severity, name,
file: (.location.file // "?"),
line: (.location.start_line // 0),
sig: (.severity + "|" + ((.identifiers[0].value // "?")|tostring) + "|" + (.location.file // "?"))}]
| map(select((.sig) as $s | ($base[0] | index($s)) | not))
' gl-sast-report.json > new_findings.json

new_count=$(jq 'length' new_findings.json)
echo "NEW High/Critical findings=${new_count}"
jq -r '.[] | "- [\(.severity)] \(.name) (\(.file):\(.line))"' new_findings.json

if [ "${new_count}" -gt 0 ]; then
echo "New High/Critical SAST findings introduced by this branch. Failing the pipeline."
exit 1
fi
echo "No new High/Critical findings vs baseline. Passing."

pages:
image: python:3.11
stage: deploy
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
repos:
- repo: https://github.com/pycqa/isort
rev: 6.0.1
rev: 8.0.1
hooks:
- id: isort

- repo: https://github.com/psf/black
rev: 25.1.0
rev: 26.5.1
hooks:
- id: black
args: [--line-length=99]
Expand Down
63 changes: 63 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,68 @@
# Change log

## [v1.3.0(WIP)+fix/partial-quant-with-rotation-bug] 2026-07-03

### Bug fix
- Fixed Hadamard online hook registration for rotation + **partial quantization** models. Previously the `down_proj` target layer classes were derived from the recorded `quant_method` (`gptq`/`dbf`/`onebit`), or by sampling the **first** `down_proj` layer's type. When a model is only partially quantized (mixed quantized / unquantized `down_proj` layers) or contains multiple `down_proj` types, hooks were registered on the wrong classes — either missing quantized layers or firing on plain `nn.Linear` — degrading rotated-model inference (`onecomp/quantized_model_loader.py`, `onecomp/runner.py`, `onecomp/pre_process/rotation_utils.py`)
- Hadamard hook target types are now derived from the actual model instead of `quant_method`. Added `collect_down_proj_types()` and `collect_quantized_down_proj_types()` to `rotation_utils.py`
- `QuantizedModelLoader` (loading from disk) uses `collect_down_proj_types()` to collect **all** distinct `down_proj` layer types from the loaded model, **including** `nn.Linear` when present (e.g. unquantized `down_proj` in a saved partial-quantization model); it intentionally does **not** filter `nn.Linear`
- `Runner` hook re-registration (during a quantization run, where some `down_proj` may still be `nn.Linear`) uses `collect_quantized_down_proj_types()`, which **excludes** `nn.Linear` so unquantized `down_proj` layers do not receive hooks; skips registration entirely when no quantized `down_proj` exists

### Test
- Added regression tests for Hadamard hook target-type collection, pinning `down_proj` type discovery for both full and partial quantization (`tests/onecomp/runner/test_hadamard_hook_type_collection.py`)

## [v1.3.0(WIP)+feature/lora-save-load-vllm-infer_jointq] 2026-06-19 16:45:00

### LoRA Adapter Sidecar Save/Load

- Updated `Runner.save_quantized_model()` to save GPTQ + LoRA SFT outputs in HF/vLLM-compatible form when `LoRAGPTQLinear` modules are present: the base quantized model is saved as normal safetensors, while LoRA weights are written as a PEFT sidecar in `lora_adapter/` (`adapter_model.safetensors`, `adapter_config.json`) (`onecomp/runner.py`)
- Uses the in-memory `self.quantized_model` when available, preserving post-process changes; falls back to `create_quantized_model()` only when no quantized model is cached
- Flattens `LoRAGPTQLinear.base_layer` tensors back to the base GPTQ key layout, excludes `lora_A` / `lora_B` tensors from base safetensors, and packs GPTQ export tensors when possible without mutating the in-memory model
- Saves LoRA adapter tensors in the base model dtype from `model_config.dtype`, avoiding an extra rounding step for bf16 models
- Updated `QuantizedModelLoader.load_quantized_model()` to auto-detect LoRA sidecars and re-wrap matching layers with `LoRAGPTQLinear` during load for save/load round-trips (`onecomp/quantized_model_loader.py`)
- Resolves adapter layers by exact match or `layers.{idx}.*` suffix when module prefixes differ, and fails fast on ambiguous LoRA suffix matches while keeping the first-match behavior for the quantized-layer load path
- Raises `ValueError` when not all adapter layers are applied, reporting applied/expected/skipped counts and pointing to the WARNING logs for skipped layer names and reasons

### GPTQ Pack State and Post-Processing

- Updated post-process workflows to keep GPTQ models packed across the Runner boundary: `Runner.run_post_processes()` passes a packed CPU quantized model to post-processors, and `PostProcessLoraSFT` temporarily unpacks GPTQ base layers for training before restoring the incoming pack state (`onecomp/runner.py`, `onecomp/post_process/post_process_lora_sft.py`)
- Added in-place pack/unpack utilities to `GPTQLinear` (`pack_in_place()`, `unpack_in_place()`) plus a shared `is_packable_wbits()` helper for AutoGPTQ-compatible packed bit-widths (`onecomp/quantizer/gptq/gptq_layer.py`)

### Examples: legacy backups

- Preserved the previous `example/post_process/example_lora_sft.py` workflow as `example/post_process/example_lora_sft_legacy.py`
- Preserved the previous `example/post_process/example_lora_sft_knowledge.py` workflow as `example/post_process/example_lora_sft_knowledge_legacy.py`

### Examples

- Updated `example/post_process/example_lora_sft.py`: end-to-end GPTQ + LoRA SFT workflow using HF-compatible save/load with a PEFT LoRA adapter sidecar, PPL evaluation, and loaded-model generation check
- Updated `example/post_process/example_lora_sft_knowledge.py`: knowledge-injection LoRA SFT example using `onecomp_knowledge.jsonl`, including save/load round-trip and output comparison
- Added `example/post_process/example_lora_sft_knowledge_jointq.py`: JointQ counterpart of the knowledge-injection LoRA SFT workflow
- Added `example/post_process/example_lora_gptq_vllm_inference.py`: end-to-end GPTQ + LoRA SFT workflow validating vLLM inference with saved LoRA adapters, including GPTQ-only vs GPTQ+LoRA output comparison

### Tests

- Extended LoRA SFT post-process tests with a JointQ smoke test (conditional on JointQ/CUDA availability), packed-in/packed-out behavior, and helper coverage for `LoRAGPTQLinear.base_layer` (`tests/onecomp/post_process/test_post_process_lora_sft.py`)
- Added `GPTQLinear` pack/unpack in-place tests covering forward-output round-trips, idempotent no-op behavior, and non-packable bit-width handling (`tests/onecomp/quantizer/gptq/test_gptq_layer_pack.py`)
- Added CPU-only save/load round-trip tests for GPTQ + LoRA SFT and non-LoRA GPTQ paths, including packed base tensors, sidecar output, reload wrapping, and logits preservation (`tests/onecomp/runner/test_lora_save_load_roundtrip.py`)
- Added `_resolve_name_by_layer_suffix()` tests covering exact, unique suffix, no-match, and ambiguous first/error modes (`tests/onecomp/runner/test_resolve_name_by_layer_suffix.py`)
- Added CPU-only LoRA adapter sidecar dtype tests covering base-dtype saves, unexpected dtype failures, and PEFT key/config conventions (`tests/onecomp/runner/test_save_lora_adapter_sidecar_dtype.py`)

## [v1.2.0+feature/legacy-vllm] 2026-06-09

### Environment updates

- Added `envs/vllm/` with versioned vLLM environment definitions (`0.12.0`, `0.15.1`).

## [v1.3.0] 2026-MM-DD (WIP)

(TODO: Add changelog for v1.3.0)

### Bug fix
- Text-only `generate()` on multimodal models (e.g. Gemma-4 12B) could emit modality delimiter tokens and degrade output after quantize→reload, because `load_quantized_model()` did not restore `generation_config.json` (including `suppress_tokens`). Now loads it from the save directory when present (`quantized_model_loader.py`).
- Fixed VLM (e.g. Gemma3) quantized model save/load: safetensors key prefixes from `save_pretrained` (`model.language_model.model.layers.*`) did not match the `from_config` model (`model.language_model.layers.*`), so `load_state_dict(..., assign=True)` left `qweight` / `scales` / `qzeros` at zero and generation degraded (`onecomp/quantized_model_loader.py`)
- Added `_remap_state_dict_keys()` to normalize checkpoint keys before `_replace_quantized_layers`; `_apply_known_state_dict_key_rewrites()` rewrites `.language_model.model.` → `.language_model.` (pattern-based, without requiring keys to exist in the empty model yet)

## [v1.2.1] 2026-07-03

### Security
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -274,10 +274,19 @@ uv run mkdocs serve

Then open [http://127.0.0.1:8000](http://127.0.0.1:8000) in your browser.

## 📓 Tutorial Notebook

Interactive walkthrough in Jupyter or [Google Colab](https://colab.research.google.com/github/FujitsuResearch/OneCompression/blob/main/notebook/01_tutorial.ipynb)
— RTN visualization, `Runner.auto_run`, and vLLM chat inference.

See [`notebook/README.md`](./notebook/README.md) for local setup, or the
[Tutorial Notebook guide](https://FujitsuResearch.github.io/OneCompression/getting-started/tutorial-notebook/) in the docs.

## 🚀 Examples

| Category | Script | Description |
|----------|--------|-------------|
| Tutorial | [01_tutorial.ipynb](./notebook/01_tutorial.ipynb) | Interactive notebook (Jupyter / Colab) |
| Quantization | [example_gptq.py](./example/example_gptq.py) | GPTQ quantization |
| | [example_qep_gptq.py](./example/example_qep_gptq.py) | GPTQ + QEP (error propagation) |
| | [example_lpcd_gptq.py](./example/example_lpcd_gptq.py) | GPTQ + QEP + LPCD quantization |
Expand Down
Loading