सामग्री पर जाएं

Opacus से डिफ़रेंशियली प्राइवेट फ़ाइन-ट्यूनिंग

DP-SGD से अपने अध्ययन के लेबल पर टेक्स्ट या इमेज क्लासिफ़ायर को फ़ाइन-ट्यून करें, epsilon और delta सेट करें, और खर्च हुई प्राइवेसी रन लॉग और मॉडल कार्ड में पढ़ें।

v2.14.0 में नया

यह ट्यूटोरियल अध्ययन के अपने लेबल पर डिफ़रेंशियल प्राइवेसी के साथ क्लासिफ़ायर प्रशिक्षित करता है, ताकि जारी किया गया मॉडल किसी एक एनोटेट किए गए आइटम के बारे में बहुत कम बताए। यह पेज उन अध्ययन स्वामियों के लिए है जिनके आइटम या लेबल संवेदनशील हैं (जैसे स्वास्थ्य रिकॉर्ड या निजी संदेश) और जो मॉडल साझा या प्रकाशित करना चाहते हैं। आप hf-text-classification के पैरामीटर में dp ब्लॉक जोड़ेंगे, ट्रेनर को उत्पाद-समीक्षा उदाहरण पर चलाएँगे, और खर्च हुई प्राइवेसी रन लॉग और मॉडल कार्ड से पढ़ेंगे। यही ब्लॉक hf-image-classification पर भी चलता है, और कोई अन्य ट्रेनर dp नहीं लेता।

डिफ़रेंशियल प्राइवेसी में epsilon और delta

डिफ़रेंशियल प्राइवेसी किसी डेटासेट पर गणना के बारे में गणितीय गारंटी है। एक रिकॉर्ड जोड़ने या हटाने से किसी भी आउटपुट की प्रायिकता एक सीमित मात्रा में बदलती है, इसलिए आउटपुट इस बारे में बहुत कम बताता है कि वह रिकॉर्ड मौजूद था या नहीं। Epsilon (ε) वह सीमा है। छोटा epsilon रिकॉर्ड के साथ और उसके बिना के आउटपुट को अलग पहचानना कठिन बनाता है, और इसलिए छोटा epsilon मज़बूत प्राइवेसी देता है। Delta (δ) वह प्रायिकता है कि epsilon की सीमा टूट जाए, और Potato के दस्तावेज़ delta को "वह संभावना कि गारंटी लागू नहीं होती" बताते हैं।

DP-SGD Abadi et al. (2016) की विधि से इस गारंटी के अंतर्गत न्यूरल नेटवर्क प्रशिक्षित करता है। हर प्रशिक्षण चरण हर आइटम के ग्रेडिएंट को अधिकतम नॉर्म तक क्लिप करता है और योग में गाउसी शोर जोड़ता है। क्लिप सीमित करता है कि एक आइटम मॉडल को कितना खिसका सकता है, और शोर उस सीमित खिसकाव को छिपाता है। Opacus एक PyTorch लाइब्रेरी है जो DP-SGD लागू करती है, और जब भी रन में dp हो Potato प्रशिक्षण लूप Opacus को सौंप देता है। Opacus का RDP एकाउंटेंट हर चरण में खर्च होने वाले epsilon को जोड़ता है।

ट्रेनर और Opacus इंस्टॉल करें

ट्रांसफ़ॉर्मर ट्रेनर को Potato के प्रशिक्षण एक्स्ट्रा से torch और transformers चाहिए। कोई Potato एक्स्ट्रा Opacus शामिल नहीं करता, क्योंकि Opacus विशिष्ट torch संस्करणों पर टिका है। रन जिस मशीन पर प्रशिक्षित होता है उस पर दोनों इंस्टॉल करें:

bash
pip install "potato-annotation[train-text]"   # [train-vision] for hf-image-classification
pip install opacus

dp वाला रन प्रशिक्षण शुरू होने से पहले प्रशिक्षण मशीन पर Opacus जाँचता है। इसलिए ssh, SLURM या एजेंट बैकएंड पर Opacus एनोटेशन सर्वर पर नहीं, बल्कि प्रशिक्षण करने वाले GPU सर्वर या कंप्यूट नोड पर जाता है। रिमोट प्रशिक्षण उन बैकएंड को समझाता है।

ट्रेनर कॉन्फ़िगर करें

नीचे का config अपना पहला मॉडल प्रशिक्षित करें का उत्पाद-समीक्षा उदाहरण है, जिसमें hf-text-classification के डिफ़ॉल्ट के रूप में निजी प्रशिक्षण सेट है। Potato के examples/ai-assisted/model-training/ से data/reviews.json और data/gold.json को प्रोजेक्ट फ़ोल्डर में कॉपी करें, और यह config वहाँ config.yaml के रूप में सहेजें:

yaml
annotation_task_name: "Review Sentiment (private training)"
 
data_files:
  - "data/reviews.json"
 
item_properties:
  id_key: "id"
  text_key: "text"
 
task_dir: "."
output_annotation_dir: "annotation_output"
 
require_password: false
admin_api_key: "demo-admin-key"
 
num_annotators_per_item: 1
 
annotation_schemes:
  - annotation_type: "radio"
    name: "sentiment"
    description: "Is this review positive or negative?"
    labels:
      - "positive"
      - "negative"
    sequential_key_binding: true
 
model_training:
  enabled: true
  trainer_params:
    hf-text-classification:
      epochs: 5
      batch_size: 16
      dp:
        epsilon: 8
        max_grad_norm: 1.0
  writeback:
    schemas: ["sentiment"]
    include_unlabeled: true
    min_confidence: 0.6

trainer_params hf-text-classification के हर रन के डिफ़ॉल्ट सेट करता है, इसलिए Training पेज का Parameters फ़ील्ड dp प्रविष्टि पहले से भरी हुई खुलता है। epsilon: 8 उस 1 से 10 की सीमा के भीतर है जिसे Potato के दस्तावेज़ सामान्य बताते हैं। delta छोड़ा गया है, इसलिए Potato delta को 1 / (10 × train आइटम) सेट करता है। max_grad_norm: 1.0 डिफ़ॉल्ट क्लिप दोहराता है। epochs और batch_size ट्रेनर के डिफ़ॉल्ट दोहराते हैं, क्योंकि Opacus दोनों से शोर का आकार तय करता है। require_password: false और सादी एडमिन कुंजी केवल लोकल परीक्षण के लिए ठीक हैं।

dp तीन कुंजियाँ लेता है:

कुंजीडिफ़ॉल्टअर्थ
epsilonआवश्यकपूरे रन का प्राइवेसी बजट। छोटा epsilon अधिक निजी है और अधिक शोर जोड़ता है।
delta1 / (10 × train आइटम)वह संभावना कि गारंटी लागू नहीं होती। Delta 1 / train आइटम से कम होना चाहिए।
max_grad_norm1.0शोर जोड़ने से पहले हर आइटम का ग्रेडिएंट इस नॉर्म तक क्लिप किया जाता है।

config python -m potato.validate_cli config.yaml --strict पास करता है। वैलिडेटर dp के लिए मैपिंग, null या false स्वीकार करता है और dp: true अस्वीकार करता है। वैलिडेटर dp के भीतर की हर कुंजी और उसकी सीमा भी जाँचता है। Opacus और train आइटम की संख्या पर निर्भर जाँचें रन शुरू होने पर, प्रशिक्षण करने वाली मशीन पर चलती हैं, जैसा रन शुरू होते समय की त्रुटियाँ सूचीबद्ध करता है।

आइटम पर लेबल लगाएँ और रन शुरू करें

hf-text-classification 20 से कम train आइटम (min_instances) फ़िट करने से इनकार करता है। सर्वर शुरू करें, फिर समीक्षाओं पर हाथ से लेबल लगाएँ या यूज़र सिम्युलेटर के तीन नकली एनोटेटरों से, जो gold फ़ाइल से उत्तर देते हैं:

bash
potato start config.yaml -p 8000
 
python -m potato.simulator --server http://localhost:8000 --users 3 \
  --strategy gold_standard --competence good=1.0 --max-annotations 40 \
  --gold-file data/gold.json --sequential --fast-mode --no-export

सिम्युलेटर 160 में से 120 समीक्षाओं पर लेबल लगाता है। डिफ़ॉल्ट splits (70% train, 15% val, 15% test) और split_seed: 0 के साथ हमारे रन ने 76 लेबल की गई समीक्षाएँ train में, 19 val में और 25 test में रखीं। इसलिए delta डिफ़ॉल्ट रूप से 1 / 760, लगभग 0.00132, होता है, और आपके सेट किया कोई भी delta 1 / 76, लगभग 0.0132, से कम होना चाहिए।

एडमिन कुंजी के साथ http://localhost:8000/admin/training खोलें, hf-text-classification और sentiment स्कीम चुनें, जाँचें कि Parameters फ़ील्ड dp प्रविष्टि दिखाता है, और Train now पर क्लिक करें। वही रन API से शुरू होता है:

bash
curl -X POST -H "X-API-Key: demo-admin-key" -H "Content-Type: application/json" \
  http://localhost:8000/admin/training/api/runs \
  -d '{"trainer": "hf-text-classification", "schemas": ["sentiment"]}'

प्रतिक्रिया में run_id होता है। रन के अपने params trainer_params को अधिलेखित करते हैं, इसलिए "params": {"dp": {"epsilon": 2}} एक रन को छोटे बजट पर प्रशिक्षित करता है, और "params": {"dp": null} या "params": {"dp": false} एक रन को DP के बिना प्रशिक्षित करता है। दोनों रन के बीच split_seed अपरिवर्तित रखें, ताकि दोनों उन्हीं आइटम पर प्रशिक्षित और स्कोर हों और होल्ड-आउट स्कोर सीधे तुलनीय रहें।

DP में रन लॉग की पंक्तियाँ

/admin/training/runs/<run_id> का रन पेज रन की घटनाएँ और मीट्रिक सूचीबद्ध करता है। DP रन घटनाओं में तीन तरह की पंक्तियाँ जोड़ता है।

पहली पंक्ति उन एम्बेडिंग तालिकाओं का नाम देती है जिन्हें Potato फ़्रीज़ करता है। टेक्स्ट ट्रांसफ़ॉर्मर की पोज़िशन और टोकन-टाइप एम्बेडिंग पूरे बैच द्वारा साझा एक पंक्ति लेती हैं, और Opacus साझा पंक्ति से होकर प्रति-आइटम ग्रेडिएंट नहीं निकाल सकता। डिफ़ॉल्ट मॉडल distilbert/distilroberta-base के लिए फ़्रीज़ की गई तालिकाएँ roberta.embeddings.position_embeddings और roberta.embeddings.token_type_embeddings हैं। फ़्रीज़ की गई तालिकाएँ प्रशिक्षित नहीं होतीं और प्राइवेसी खर्च नहीं करतीं, और शब्द एम्बेडिंग तथा हर अन्य परत फिर भी प्रशिक्षित होती हैं।

दूसरी पंक्ति DP-SGD: से शुरू होती है और लक्ष्य epsilon, delta, योजनाबद्ध एपॉक, Opacus का चुना शोर गुणक, प्रति-आइटम क्लिप और सैंपलिंग दर बताती है। हर चरण पॉइसन सैंपलिंग से बैच खींचता है, इसलिए हर train आइटम प्रायिकता 1 / प्रति एपॉक बैच के साथ स्वतंत्र रूप से बैच में आता है। 16 के बैच में 76 train आइटम के साथ एपॉक में 5 बैच होते हैं और लॉग सैंपलिंग दर 0.2000 देता है। शोर गुणक शोर का मानक विचलन तय करता है, और Opacus का FAQ सामान्य सीमा 0.1 से 2 देता है।

हर एपॉक के बाद Epoch <n>/<epochs>: loss <loss>, epsilon spent <epsilon> रूप की पंक्ति एपॉक की औसत हानि और अब तक खर्च हुआ epsilon रिपोर्ट करती है। वही मान प्रति एपॉक dp_epsilon मीट्रिक के रूप में दर्ज होता है, और रन की अंतिम मीट्रिक में पूरे रन का dp_epsilon होता है। Opacus शोर का आकार ऐसे तय करता है कि योजनाबद्ध एपॉक अधिकतम लक्ष्य epsilon खर्च करें। जो रन patience पर जल्दी रुकता है (डिफ़ॉल्ट रूप से बेहतर val स्कोर के बिना दो एपॉक) वह लक्ष्य से कम खर्च करता है।

मॉडल कार्ड में dp प्रविष्टि

रन model_card.json को रन डायरेक्टरी के artifacts/ में, <task_dir>/<output_annotation_dir>/training/runs/<run_id>/ में, लिखता है। DP रन के कार्ड में dp प्रविष्टि होती है:

फ़ील्डमान
epsilon_targetआपका माँगा epsilon
epsilon_spentरन ने क्या खर्च किया, Opacus के RDP एकाउंटेंट से
deltaरन का उपयोग किया delta, आपका अपना या डिफ़ॉल्ट
max_grad_normप्रति-आइटम क्लिप
noise_multiplierOpacus का चुना शोर गुणक
accountantrdp
coverstrain split

epsilon_spent रन के प्रशिक्षित हर एपॉक को गिनता है। रखे गए चेकपॉइंट के बाद के एपॉक भी कुल में गिने जाते हैं। Hugging Face Hub पर प्रकाशित करना model_card.json को मॉडल के साथ अपलोड करता है, लोकल पाथ को फ़ाइल नामों से बदलकर, इसलिए dp प्रविष्टि वेट के साथ यात्रा करती है। Hub पर README.md मॉडल कार्ड में भी "Differential privacy" पंक्ति होती है, जिसमें लक्ष्य के विरुद्ध खर्च हुआ epsilon, delta और वह train स्प्लिट है जिसे गारंटी कवर करती है। जब रन ने लक्ष्य या delta दर्ज नहीं किया हो, तो पंक्ति उसे छोड़ देती है।

प्राइवेसी बजट और क्लिप चुनना

Potato के दस्तावेज़ epsilon की सामान्य सीमा 1 से 10 देते हैं और delta को 1 / train आइटम से कम माँगते हैं। Opacus का FAQ delta के लिए वही अंगूठा-नियम देता है और बहुत छोटे delta के साथ epsilon के लिए छोटा स्थिरांक सुझाता है। 1 / (10 × train आइटम) का डिफ़ॉल्ट delta 1 / train आइटम की सीमा के नीचे है, इसलिए अधिकतर अध्ययन delta छोड़ सकते हैं।

क्लिप, max_grad_norm, दो त्रुटियों के बीच समझौता करता है। क्लिपिंग सीमा से बड़े हर ग्रेडिएंट को बदल देती है, और Opacus का FAQ कहता है कि क्लिपिंग अभिसरण को बिगाड़ती है। शोर क्लिप के अनुपात में होता है, इसलिए बड़ा क्लिप अधिक शोर जोड़ता है। FAQ आगे कहता है कि गलत सीमा रैखिक मॉडल को गहरे मॉडल से अधिक नुकसान पहुँचाती है। डिफ़ॉल्ट 1.0 से शुरू करें और क्लिप ट्यून करने से पहले होल्ड-आउट स्कोर की तुलना करें।

Opacus शोर का आकार योजनाबद्ध epochs के लिए तय करता है, इसलिए कम एपॉक पर फैला वही epsilon हर चरण में कम शोर का अर्थ रखता है। Opacus का FAQ बताता है कि बड़ा बैच सैंपलिंग दर बढ़ाता है और सैंपलिंग दर के साथ प्राइवेसी की कीमत भी। FAQ कीमत की भरपाई के लिए बड़ी लर्निंग रेट और जल्दी रुकना सुझाता है। DP रन के होल्ड-आउट स्कोर की तुलना उसी स्प्लिट पर dp के बिना रन के स्कोर से करें। दोनों स्कोर का अंतर नापता है कि आपके डेटा पर गारंटी की कीमत क्या है।

गारंटी का दायरा

गारंटी train स्प्लिट को कवर करती है। एक train आइटम बदलने से जारी किया गया मॉडल अधिकतम बताए गए epsilon जितना ही बदल सकता है। आइटम उस लेबल के साथ गिना जाता है जो आइटम के एनोटेटरों से समाधानित हुआ। Potato गारंटी प्रति आइटम बताता है, और दस्तावेज़ प्रति एनोटेटर कोई गारंटी नहीं बताते।

val स्प्लिट गारंटी के बाहर है। हर एपॉक के बाद ट्रेनर मॉडल को val आइटम पर स्कोर करता है और सबसे अच्छे स्कोर वाले एपॉक का चेकपॉइंट रखता है। वह चुनाव val आइटम के लेबल बिना शोर जोड़े पढ़ता है, इसलिए मॉडल कार्ड का epsilon val आइटम के बारे में कोई वादा नहीं करता। जब val आइटम को train आइटम जितनी सुरक्षा चाहिए, तब val अंश 0 कर दें और अंश test में ले जाएँ, जैसे splits: {train: 0.7, val: 0, test: 0.3}। val आइटम के बिना ट्रेनर अंतिम एपॉक रखता है, patience रन को कभी जल्दी नहीं रोकता, और होल्ड-आउट स्कोर test से आता है। train अंश अपरिवर्तित रखने से वही आइटम train में रहते हैं, क्योंकि Potato स्प्लिट हर आइटम की आईडी के सीड वाले हैश से देता है।

मॉडल की लेबल सूची गारंटी के बाहर है। Potato लेबल सूची डेटा में दिखने वाले लेबल से पढ़ता है, इसलिए जो लेबल एनोटेटरों ने केवल एक आइटम पर उपयोग किया वह भी मॉडल के आउटपुट में दिखता है।

DP में प्रशिक्षण के अंतर

DP-SGD को हर आइटम का ग्रेडिएंट चाहिए, इसलिए DP रन उसी ट्रेनर के सामान्य रन से इन तरीकों से अलग है:

  • प्रशिक्षण पूर्ण सटीकता में चलता है, precision जो भी कहे, क्योंकि DP में मिश्रित सटीकता बंद है।
  • gradient_accumulation 1 होना चाहिए। हर चरण एक पॉइसन-सैंपल किए बैच पर प्रशिक्षित होता है।
  • क्वांटाइज़ किया बेस मॉडल (lora.quantize) अस्वीकार किया जाता है।
  • टेक्स्ट ट्रांसफ़ॉर्मर की पोज़िशन और टोकन-टाइप एम्बेडिंग तालिकाएँ फ़्रीज़ की जाती हैं, जैसा रन लॉग रिपोर्ट करता है।
  • जिस मॉडल में ऐसी परत हो जिसे Opacus समर्थन नहीं देता, जैसे BatchNorm, वह प्रशिक्षण की शुरुआत में परत का नाम देकर विफल होता है।

केवल hf-text-classification और hf-image-classification dp लेते हैं। हर अन्य ट्रेनर वह पैरामीटर अस्वीकार करता है जो वह नहीं लेता, इसलिए sklearn-text, setfit या hf-token-classification पर dp trainer_params के नीचे बूट पर और रन शुरू होने पर 409 के साथ विफल होता है।

रन शुरू होते समय की त्रुटियाँ

potato validate सर्वर शुरू होने से पहले वह कुंजी जो dp नहीं लेता और सीमा से बाहर का मान रिपोर्ट करता है। रन शुरू होने पर dp ब्लॉक फिर से जाँचता है, Opacus और train स्प्लिट पर निर्भर सीमाओं के साथ। जो रन इन जाँचों में विफल होता है वह प्रशिक्षण से पहले त्रुटि के साथ समाप्त होता है, कोड validation_failed के साथ और हर समस्या एक संदेश में। संदेश Potato की जाँचों से आते हैं:

समस्यासंदेश
Opacus इंस्टॉल नहींdp needs opacus, which is not installed (pip install opacus).
epsilon नहींdp needs epsilon, the privacy budget for the run (1 to 10 is usual).
ऐसी कुंजी जो dp नहीं लेताdp does not take bogus; it takes epsilon, delta and max_grad_norm.
delta 1 / train आइटम के बराबर या ऊपरdp.delta is 0.05, at least 1 / 76 train items: at that delta one item's data could be released outright. Use less than 0.0131579.
gradient_accumulation 1 से ऊपरdp trains one sampled batch per step; set gradient_accumulation to 1.
lora.quantize सेटdp cannot train a quantized (4bit or 8bit) base model; drop lora.quantize.

खाली मैपिंग dp: {} बिना बजट के DP माँगती है और epsilon-गायब संदेश के साथ विफल होती है। जब trainer_params dp सेट करे, तब रन का "dp": null या "dp": false उस रन के लिए DP बंद कर देता है। स्टेटस रूट GET /admin/training/api/status वही संदेश errors के नीचे सूचीबद्ध करता है।

आगे पढ़ें

संदर्भ