2017-05-23 3 views
17

मुझे एक पदानुक्रमित सॉफ्टमैक्स मॉडल को लागू करने में दिलचस्पी है जो 10 एम कक्षाओं के क्रम पर बड़े शब्दावली को संभाल सकता है। बड़े वर्ग की गणना और कुशल दोनों के लिए स्केलेबल दोनों के लिए ऐसा करने का सबसे अच्छा तरीका क्या है? उदाहरण के लिए, कम से कम one paper दिखाया गया है कि 2-स्तरीय पेड़ का उपयोग करते समय एचएस बड़े vocabs के लिए ~ 25x स्पीडअप प्राप्त कर सकता है जहां प्रत्येक नोड sqrt(N) कक्षाएं। मैं एक मनमानी गहराई के पेड़ के लिए एक मनमाना शाखा के कारक के साथ एक और सामान्य संस्करण में भी रूचि रखता हूं।टेन्सफोर्लो में स्केलेबल, कुशल पदानुक्रमित सॉफ्टमैक्स?

1) हर बैच, जहां हम सूचकांक और विभाजन इकट्ठा के लिए भागो tf.gather:

वहाँ कुछ ही विकल्प है कि मैं यहाँ देख रहे हैं। इससे बड़े बैच आकार और वसा वाले पेड़ों के साथ समस्याएं पैदा होती हैं जहां अब गुणांक को बहुत अधिक डुप्लिकेट किया जा रहा है, जिससे ओओएम त्रुटियां होती हैं।

2) # 1 के समान, हम tf.embedding_lookup का उपयोग कर सकते हैं जो ओओएम त्रुटियों के साथ मदद करेगा लेकिन अब सब कुछ सीपीयू पर रखता है और चीजों को धीमा कर देता है।

3) प्रत्येक नमूना को अलग से संसाधित करने के लिए parallel_iterations=1 के साथ tf.map_fn का उपयोग करें और एकत्रित करने के लिए वापस जाएं। यह बहुत अधिक स्केलेबल है लेकिन धारावाहिकरण के कारण वास्तव में 25x स्पीडअप के करीब नहीं आता है।

क्या एचएस लागू करने का कोई बेहतर तरीका है? गहरे और संकीर्ण बनाम छोटे और चौड़े पेड़ के लिए अलग-अलग तरीके हैं? काफ़ी नीचे

लेकिन अब CPU पर सब कुछ रहता है और धीमा कर देती चीजों

और 300 यूनिट छिपा आकार का उपयोग करना चाहते हैं और:

+0

वे कार्य के आधार पर भिन्न होते हैं। भाषा मॉडल के चारों ओर छिपे हुए आकार के साथ 400 के आसपास बड़े बैचों हैं; अन्य कार्यों में छोटे बैच आकार और बड़े छिपे हुए आकार हो सकते हैं, जैसे कल्पना वर्गीकरण। वीआरएएम और रैम समस्या से काफी बड़े हैं (हालांकि जीपीयू रैम नहीं है)। –

+0

क्या मैं टेन्सफोर्लो में आपके एचएस कार्यान्वयन को देख सकता हूं? मुझे वर्तमान में भी इसकी आवश्यकता है। –

+1

यह थोड़ा गन्दा है, लेकिन यहां देखें: https://github.com/tansey/sdp/blob/87e701c9b0ff3eacab29713cb2c9e7181d5c26aa/tfsdp/models.py#L205 - पीछे की ओर, मैं pytorch या किसी अन्य गतिशील ग्राफ ढांचे का उपयोग करने का सुझाव दूंगा। –

उत्तर

7

आप पाएंगे कि आप GPU स्तरीय प्रदर्शन चाहते उल्लेख 10 एम शब्दकोष शब्दकोश।

इसका मतलब है कि (float32 मानते हुए), आपको आउटपुट परत के लिए पैरामीटर और ढाल को स्टोर करने के लिए केवल 4 * 300 * 10 एम * 2 बाइट्स = 24 जीबी की आवश्यकता होगी।

पदानुक्रमित सॉफ़्टमैक्स (एचएसएम) स्मृति आवश्यकताओं को कम नहीं करता है - यह केवल प्रशिक्षण को गति देता है।

वास्तविक, आप, एक बहुत अधिक GPU स्मृति की आवश्यकता होगी क्योंकि आप भी स्टोर करने के लिए की आवश्यकता होगी:

  • अन्य पैरामीटर और उनके ढ़ाल

  • अनुकूलक डेटा, उदा गति प्रशिक्षण में वेग

  • सक्रियण और अस्थायी डेटा backpropagated

  • ढांचा विशेष भूमि के ऊपर

इसलिए, अगर आप GPUs पर सभी गणना करना चाहते हैं, तो आप कोई होगा पसंद है लेकिन इस परत को कई उच्च-स्मृति GPUs में वितरित करने के लिए।

इस ठोस बनाने के लिए, मान लीजिए कि आप (कुल 9M शब्द) 3K वर्गों के साथ एक 2-स्तर HSM, वर्ग प्रति 3K शब्दों के साथ है लगता है:

हालांकि, अगर आप अब एक और समस्या है। आप 8 जीपीयू में 3 के वर्गों को वितरित करते हैं, ताकि प्रत्येक 384 कक्षाएं होस्ट कर सकें।

क्या होगा यदि बैच में सभी लक्षित शब्द समान 384 वर्ग, से हैं वे एक ही जीपीयू से संबंधित हैं? एक जीपीयू सभी काम करेगा, जबकि अन्य 7 इसके लिए इंतजार करेंगे।

समस्या यह है कि यदि बैच में लक्षित शब्द अलग-अलग GPUs से संबंधित हैं, तो भी आप सबसे खराब स्थिति परिदृश्य में समान प्रदर्शन करेंगे, अगर आप टेंसरफ्लो में यह गणना करना चाहते हैं (ऐसा इसलिए है क्योंकि TensorFlow एक "निर्दिष्ट और रन" रूपरेखा है - कम्प्यूटेशनल ग्राफ सबसे अच्छा मामले और सबसे ज्यादा मामले)

दोनों को ऐसा करने के लिए बड़ा वर्ग की गिनती के लिए स्केलेबल होना सबसे अच्छा तरीका क्या है के लिए एक ही है और कुशल?

मॉडल समांतरता की उपरोक्त अक्षमता (प्रत्येक जीपीयू को पूरे बैच को संसाधित करना चाहिए) बताता है कि किसी को सब कुछ एक ही स्थान पर रखने की कोशिश करनी चाहिए।

मान लीजिए कि आप मेजबान पर या 1 humongous GPU पर सब कुछ लागू कर रहे हैं।

  1. आप दृश्यों मॉडलिंग नहीं कर रहे हैं, या आप कर रहे हैं, लेकिन वहाँ पूरे अनुक्रम के लिए केवल एक ही उत्पादन, मानकों को कॉपी, जो करने के लिए आप के लिए भेजा से तो स्मृति भूमि के ऊपर है, स्मृति की तुलना में नगण्य है अगर आवश्यकताओं ऊपर वर्णित:

    400 == बैच आकार < कक्षाएं == 3K

    की < संख्या इस मामले में, आप बस इस्तेमाल कर सकते हैं gather या embedding_lookup (हालांकि नकल अक्षम है)

  2. +०१२३५१६४१०६१
  3. हालांकि, यदि आप लंबाई के मॉडल अनुक्रम करते हैं, तो 100, हर समय चरण के साथ आउटपुट के साथ, पैरामीटर प्रतिलिपि एक बड़ी समस्या बन जाती है।

    इस मामले में, मुझे लगता है कि आपको सी ++/सीयूडीए सी पर छोड़ना होगा और इस पूरे परत और इसके ढाल को कस्टम सेशन के रूप में लागू करना होगा।

+0

तो आप कह रहे हैं कि इसे लागू करने का एकमात्र प्रभावी तरीका मानक 'एम्बेडिंग_lookup' का उपयोग करना है जिसे मैंने # 2 में सुझाया था? यह उचित लगता है, लेकिन मुझे आश्चर्य होगा कि आप वास्तव में जीपीयू को कितनी हद तक देखेंगे कि आप असली दुनिया के डेटासेट पर वर्णन कर रहे हैं, जो कि मैं जो खोज रहा हूं वह है। इसके अलावा, नमूने वाले सॉफ्टमैक्स की तुलना उस पेपर में की जाती है जिसे मैंने लिंक किया है और इसकी तुलना कई अन्य कागजात में पूरी तरह से की गई है। –

+0

इसके अलावा, अगर कोई एक GPU पर सब कुछ संभाल सकता है तो क्या होगा? भविष्य में कहें कि उदाहरण के लिए मेरे पास 32 जीबी जीपीयू है। –

+0

@WesleyTansey "नमूना सॉफ्टमैक्स की तुलना में तुलना की जाती है" - अब मैं इसे देखता हूं। यह और अन्य अपडेट देखें। – MaxB

संबंधित मुद्दे