
संदर्भ कार्यान्वयन एक मल्टी-बिट LLM वॉटरमार्किंग योजना का, जो कोडित पेलोड स्प्रेडिंग, अनबायस्ड रीवेटिंग, और सॉफ्ट-डिसीजन ECC डिकोडिंग का उपयोग करके उत्पन्न टेक्स्ट में संदेशों को एम्बेड और डिटेक्ट करता है।
कोडेड पेलोड स्प्रेडिंग के माध्यम से रोबस्ट और स्केलेबल मल्टी-बिट LLM वॉटरमार्किंग का संदर्भ कार्यान्वयन।
WeaveMark LLM-जनित टेक्स्ट में k-बिट संदेश एम्बेड करता है, जबकि टोकन वितरण को निष्पक्ष (unbiased) बनाए रखता है। यह कोडेड पेलोड स्प्रेडिंग (प्रति टोकन κ कोडवर्ड बिट्स, ℓ परतों पर, संदर्भ-शफ़ल्ड परत→बिट असाइनमेंट के साथ), प्रति-बिट वोट मार्जिन से सॉफ्ट-डिसीजन ECC डिकोडिंग, और निष्पक्ष मल्टीलेयर रीवेटिंग (प्रत्येक दिशा को संदर्भ कॉइन फ्लिप के साथ XOR किया गया) को जोड़ता है। संदेश के बजाय संदर्भ से विभाजित समर्पित ज़ीरो-बिट परतें, संदेश-स्वतंत्र उपस्थिति का पता लगाने की सुविधा देती हैं।
weavemark/ लाइब्रेरी
watermark.py WeaveMark लॉगिट्स प्रोसेसर (एम्बेडिंग)
extraction.py extract_bits, detect_zerobit
prf.py कीड PRF (एम्बेड/एक्सट्रैक्ट द्वारा साझा)
data.py डेटासेट लोडिंग, प्रॉम्प्ट तैयारी, JSONL रिकॉर्ड
device.py CUDA जाँच
ecc/ Golay, Reed-Muller, सॉफ्ट-डिसीजन डिकोडर
generate.py वॉटरमार्क्ड / सादा टेक्स्ट जनरेट करें
detect.py एक्सट्रैक्शन + ज़ीरो-बिट z-score + PPL
evaluate_downstream.py सारांशीकरण / अनुवाद गुणवत्ता
perplexity.py PPL स्कोरर
attacks/ प्रतिस्थापन, DIPPER
run_*.py पाइपलाइन (generate+detect, attacks, downstream)
data/OpenGen.jsonl OpenGen प्रॉम्प्ट (--dataset opengen); नीचे नोट देखें
data/OpenGen.jsonl (मानक सार्वजनिक OpenGen बेंचमार्क) आकार के कारण इस संग्रह से हटा दिया गया है; --dataset opengen उपयोग करने के लिए इसे data/ के अंतर्गत रखें। c4 और openwebtext डेटासेट Hub से स्ट्रीम होते हैं और उन्हें किसी स्थानीय फ़ाइल की आवश्यकता नहीं होती।
सभी स्क्रिप्ट्स को रिपॉजिटरी रूट से चलाएँ ताकि import weavemark हल हो सके।
Python 3.10–3.12 और CUDA GPU की आवश्यकता है (मॉडल bitsandbytes के माध्यम से 4-bit लोड होते हैं; कोई CPU पथ नहीं है)। 4-bit LLaMA-3-8B ~16 GB में फिट होता है।
cd WeaveMark
python -m venv .venv && source .venv/bin/activate # या: conda create -n weavemark python=3.11
requirements.txt से पहले PyTorch का CUDA बिल्ड इंस्टॉल करें — सादा pip install torch Windows पर CPU-केवल व्हील देता है, और व्हील में आपके GPU के लिए कर्नेल होने चाहिए (RTX 50-सीरीज़ / sm_120 को CUDA ≥ 12.8 पर torch ≥ 2.7 चाहिए; पुराने cu121 व्हील sm_90 पर रुक जाते हैं और रनटाइम पर विफल होते हैं)। https://pytorch.org से मेल खाता कमांड चुनें।
pip install torch --index-url https://download.pytorch.org/whl/cu128 # उदाहरण: Blackwell
pip install -r requirements.txt
जाँचें कि GPU वास्तव में कर्नेल चलाता है (is_available() अकेला पर्याप्त नहीं है — यह True होता है तब भी जब व्हील में आर्क के लिए कर्नेल न हों):
python -c "import torch; t=torch.zeros(8).cuda().normal_(); print(torch.__version__, torch.cuda.get_device_capability(), (t*t).sum().item())"
LLaMA-3 और C4 गेटेड हैं: huggingface-cli login करें और उनकी शर्तें स्वीकार करें। OpenGen रिपो के साथ आता है। CUDA_VISIBLE_DEVICES=<i> के साथ GPU चुनें।
python generate.py --method weavemark --ecc_method rm --random_message \
--dataset c4 --num_test 100 --max_new_tokens 200 \
--bpt 10 --num_layers 10 --window_size 2 --prob_delta 1.0 \
--num_zerobit_layers 0 --do_sample
python detect.py --data_dir output_dump/<run_folder> --detect --stride 25
detect.py detailed_eval_*.csv और summary_eval_*.csv लिखता है; मुख्य कॉलम success_rate हैं और, --zerobit_threshold के साथ, z_success_rate। run_main.py generate + detect को जोड़ता है (इसके शीर्ष पर स्थिरांक संपादित करें)।
डेटासेट: c4 / openwebtext Hub से स्ट्रीम होते हैं और --prompt_len शब्दों तक ट्रंकेट होते हैं; opengen data/OpenGen.jsonl पढ़ता है और प्रत्येक प्रीफिक्स को --prompt_len टोकन तक ट्रंकेट करता है।
ECC msg→codeword: golay 12→24, rm 16→32, dual_golay 24→48, dual_rm 32→64। none --message को बिना कोड के एम्बेड करता है।
पेपर सेटिंग्स: मल्टी-बिट ट्रेसिंग --bpt 10 --num_layers 10 --window_size 2 --prob_delta 1.0 --num_zerobit_layers 0 का उपयोग करती है, ECC संदेश लंबाई के अनुसार; संयुक्त सेटिंग के लिए --num_zerobit_layers 2 --enable_zerobit जोड़ें; शुद्ध ज़ीरो-बिट है --bpt 0 --num_layers 0 --num_zerobit_layers 10 --enable_zerobit।
python attacks/substitution.py --data_dir output_dump/<run> --ratios 0.1 0.2 0.3
python attacks/dipper_attack.py --data_dir output_dump/<run> --lex_diversity 20 --order_diversity 20
python detect.py --data_dir output_dump/<run> --text_file attacked_text_10.jsonl --detect --stride 999
run_substitution.py / run_dipper.py हमले + पूरे-टेक्स्ट डिटेक्शन को जोड़ते हैं (--stride 999 प्रत्येक क्रॉप को पूरा मूल्यांकन करता है)। run_downstream.py BERTScore + ROUGE/BLEU के साथ सारांशीकरण (CNN/DailyMail) और अनुवाद (WMT16 en→ro) चलाता है।
window_size = 2: निष्पक्ष डिज़ाइन संदर्भ के पुन: उपयोग को मना करता है, इसलिए बड़ी विंडो स्किप हानि को कम करती है (परिशिष्ट देखें)।no_watermark रन गलत-सकारात्मक दर मापने के लिए समान कुंजियों/पैरामीटरों का पुन: उपयोग करते हैं।@inproceedings{weavemark,
title = {Robust and Scalable Multi-bit LLM Watermarking via Coded Payload Spreading},
author = {Anonymous},
year = {2026},
note = {Under review}
}
attacks/dipper.py को martiansideofthemoon/ai-detection-paraphrases से अनुकूलित किया गया है (इसका लाइसेंस उस फ़ाइल पर लागू होता है)। MIT के तहत जारी (देखें LICENSE); प्रकाशित करने से पहले कॉपीराइट धारक सेट करें।
| फ़्लैग | प्रतीक | अर्थ | विशिष्ट |
|---|
--bpt | κ | बिट्स प्रति टोकन | 10 |
--num_layers | ℓ | मल्टी-बिट परतें | 10 |
--window_size | h | संदर्भ विंडो | 2 |
--prob_delta | δ | रीवेटिंग शक्ति | 1.0 |
--ecc_method | — | none/golay/dual_golay/rm/dual_rm | rm |
--num_zerobit_layers | ℓ_z | ज़ीरो-बिट परतें | 0 या 2 |
--top_k | K | सैंपलिंग top-k | 50 |