
एलएलएम चैट टोकन विकल्पों में अंकगणित/डिस्कॉप स्टेग्नोग्राफ़िक कोडर का उपयोग करके कई गुप्त संदेश एम्बेड करें, बिट-सटीक डिकोडिंग और स्टेग्नालिसिस मूल्यांकन के साथ।
यह LLM चैट संवादों पर भाषाई स्टेग्नोग्राफ़ी के लिए शोध कोड है, जिसमें एक सिंगल-स्ट्रीम बेसलाइन और एक बैच्ड मल्टी-स्ट्रीम (HiTMS) प्रोटोकॉल है जो एक साथ कई स्वतंत्र गुप्त संदेश छिपाता है और अधिक थ्रूपुट के लिए GPU बैचिंग का लाभ उठाता है।
एक Bob मॉडल प्रश्न पूछता है; एक Alice मॉडल उत्तर देता है, गुप्त रूप से पेलोड को एक स्टेग्नोग्राफ़िक कोडर के ज़रिए अपने टोकन विकल्पों में एनकोड करता है; Bob, Alice के उत्तर पर मॉडल फिर से चलाकर बिट्स पुनर्प्राप्त करता है। एनकोडिंग और डिकोडिंग बिट-एक्ज़ैक्ट हैं, इसलिए गुप्त संदेश बिना किसी हानि के पुनर्प्राप्त हो जाता है।
arithmetic*.py)discop*.py)single_stream.py): कोई फ्रेमिंग ओवरहेड नहीं —
हर चैनल बिट पेलोड है (~100% उपयोग)।protocol.py): m गुप्त स्ट्रीम को राउंड्स में
विभाजित किया जाता है, एक PRF-संचालित स्ट्रीम→स्लॉट मैपिंग, डिकॉय स्लॉट्स, 16-बिट लंबाई
हेडर, और एक फिलर कीस्ट्रीम। प्रति राउंड कई प्रतिक्रियाएँ जनरेट होती हैं
एक बैच्ड फॉरवर्ड पास में, इसलिए थ्रूपुट बैच आकार के साथ बढ़ता है।प्रयोगों में उपयोग किए गए मॉडल: meta-llama/Llama-3.2-3B-Instruct और
google/gemma-3-4b-it। डेटासेट:
databricks/databricks-dolly-15k और HuggingFaceH4/no_robots के क्रिएटिव/ओपन-एंडेड सबसेट।
data/ पेपर में हर प्रयोग के परिणाम रखता है — क्षमता,
थ्रूपुट, उपयोग, जज स्कोर और डिटेक्टर AUROC — प्रति ट्रायल एक JSON ऑब्जेक्ट
के रूप में। पूर्ण स्कीमा के लिए data/README.md देखें।
जनरेट किया गया स्टेगोटेक्स्ट स्वयं शामिल नहीं है: कच्चे लॉग में
हर फ्रैगमेंट के लिए प्रश्न और प्रतिक्रिया अंतर्निहित होती है, जिससे वे ~1 GB हो जाते हैं, इसलिए
export_data.py उन फ़ील्ड्स को हटा देता है और हर माप (~24 MB) रखता है। सभी
ड्राइवर सीडेड हैं, इसलिए स्वीप फिर से चलाने पर टेक्स्ट ठीक वैसे ही पुनर्जनित होता है।
कच्ची आउटपुट डायरेक्टरीज़ (
sweep_logs/,single_sweep_logs/,scaling_logs/,judge_logs/,cover_logs/,run_logs/,steganalysis_logs/) gitignored हैं — वे बड़ी हैं (अंतिम में मल्टी-GB प्रशिक्षित डिटेक्टर चेकपॉइंट्स होते हैं) और पूरी तरह पुनर्जनन योग्य हैं।
conda create -n ems python=3.10 -y && conda activate ems
pip install torch transformers datasets numpy
pip install openai # only needed for judge_quality.py
LLM चलाने के लिए CUDA GPU आवश्यक है। Llama और Gemma चेकपॉइंट्स
Hugging Face Hub पर गेटेड हैं, इसलिए पहली बार उपयोग से पहले huggingface-cli login चलाएँ
(उन मॉडलों तक पहुँच मिलने के साथ)।
प्रश्न पूल बनाएँ (एक बार):
python build_question_pool.py # -> dolly15k_creative_questions.json
python build_norobots_pool.py # -> norobots_creative_questions.json
एकल विस्तृत ट्रायल (सैनिटी जाँच):
# multi-stream
CUDA_VISIBLE_DEVICES=0 python multi_round_demo.py
# single-stream
CUDA_VISIBLE_DEVICES=0 python single_stream_demo.py
# override model / coder / pool via env
ROUND_TRIP_MODEL=google/gemma-3-4b-it STEGO_ALGORITHM=discop \
STEGO_QUESTION_POOL=norobots_creative_questions.json \
CUDA_VISIBLE_DEVICES=0 python multi_round_demo.py
पूर्ण प्रयोग (फिर से शुरू करने योग्य — जारी रखने के लिए वही कमांड दोबारा चलाएँ):
# multi-stream (8 streams x 1024 bits), all model/pool/coder combos, 500 trials
CUDA_VISIBLE_DEVICES=0 python run_sweep.py --trials 500
# single-stream baseline
CUDA_VISIBLE_DEVICES=0 python run_single_sweep.py --trials 500
# stream-count scaling (dolly + Llama + Discop)
CUDA_VISIBLE_DEVICES=0 python run_scaling_sweep.py --x-values 4 8 16 32 64
अगोचरता मूल्यांकन (OPENAI_API_KEY में या स्थानीय OPENAI_API_key.txt में OpenAI कुंजी आवश्यक है, दोनों gitignored):
python judge_quality.py --dry-run # plan only, no API calls
python judge_quality.py --limit 2 # tiny live smoke test
python judge_quality.py # full run (resumable)
python judge_quality.py --aggregate-only # recompute the score table
प्रत्येक ड्राइवर अपने सीड्स (प्रॉम्प्ट शफलिंग, पेलोड सैंपलिंग, सैंपलिंग RNG,
torch.manual_seed) स्थिर करता है और एक नियतात्मक, पास-जागरूक
प्रॉम्प्ट स्ट्रीम से प्रॉम्प्ट उपभोग करता है, इसलिए पूरा स्वीप अंत-से-अंत पुनरुत्पादनीय है और बाधा के बाद
अपने चेकपॉइंट से ठीक उसी स्थान से फिर से शुरू होता है।
OPENAI_API_key.txt, *.key, और .env अनदेखा किए जाते हैं।| Path | Description |
|---|
arithmetic.py, arithmetic_batch.py | अरिथमेटिक-कोडिंग स्टेगो (सिंगल + बैच्ड स्ट्रीम एनकोडर/डिकोडर)। |
discop.py, discop_batch.py | Discop स्टेगो कोडर + साझा PRG (सिंगल + बैच्ड)। |
utils.py | साझा सहायक (बिट/इंट रूपांतरण, एन्ट्रॉपी, top-k, वाक्य-समाप्ति जाँच)। |
protocol.py | मल्टी-स्ट्रीम HiTMS प्रोटोकॉल (स्ट्रीम मैपिंग, डिकॉय, हेडर, फिलर)। |
single_stream.py | सिंगल-स्ट्रीम प्रोटोकॉल (कोई फ्रेमिंग नहीं; L-वें बिट पर ट्रंकेट करें)। |
round_trip.py, batch_round_trip.py | न्यूनतम वन-शॉट राउंड-ट्रिप डेमो/परीक्षण। |
multi_round_demo.py | मल्टी-स्ट्रीम ट्रायल रनर (run_trial) + विस्तृत सिंगल-ट्रायल डेमो। |
single_stream_demo.py | सिंगल-स्ट्रीम ट्रायल रनर (run_single_trial) + डेमो। |
run_sweep.py | {model}×{pool}×{coder} पर मल्टी-स्ट्रीम स्वीप, फिर से शुरू करने योग्य। |
run_single_sweep.py | सिंगल-स्ट्रीम समकक्ष स्वीप। |
run_scaling_sweep.py | स्ट्रीम-गिनती स्केलिंग स्वीप (x ∈ {1,2,4,8,16,32,64}), किसी भी मॉडल/पूल/कोडर के लिए। |
run_x1_shards.py, run_x1_finish.sh, merge_x1_shards.py | x=1 एब्लेशन: एक सेल को GPU पर शार्ड करें, फिर कवरेज जाँच के साथ मर्ज करें। |
judge_quality.py | LLM-एज़-ए-जज अगोचरता स्कोरर (प्रति कॉल एक QA, फिर से शुरू करने योग्य)। |
gen_cover.py | पेलोड-मुक्त "कवर" टेक्स्ट जनरेशन (स्टेगेनालिसिस संदर्भ)। |
steganalysis_bert.py | कवर-बनाम-स्टेगो डिटेक्टर (BERT / RoBERTa / DeBERTa-v3 / ELECTRA)। |
export_data.py | data/ में प्रकाशन-योग्य केवल-सारांश मिरर बनाता है। |
build_question_pool.py, build_norobots_pool.py | HF डेटासेट से प्रश्न पूल बनाते हैं। |
*_creative_questions.json | पूर्व-निर्मित प्रश्न पूल। |
legacy/ | पिछली स्क्रिप्ट / पूल, संदर्भ के लिए रखे गए। |