AWS Graviton पर PyTorch मॉडल अनुमान का अनुकूलन
Latest Technology, (लेटेस्ट टेक न्यूज़) Gadget (गैजेट्स) …
एआई/एमएल मॉडल बेहद महंगा प्रयास हो सकता है। हमारे कई पोस्ट एआई/एमएल वर्कलोड के रनटाइम प्रदर्शन का विश्लेषण और अनुकूलन करने के लिए विभिन्न प्रकार की युक्तियों, युक्तियों और तकनीकों पर केंद्रित हैं। हमारा तर्क दोहरा रहा है:
- प्रदर्शन विश्लेषण और अनुकूलन प्रत्येक एआई/एमएल विकास परियोजना की एक अभिन्न प्रक्रिया होनी चाहिए, और,
- सार्थक प्रदर्शन को बढ़ावा देने और लागत में कमी लाने के लिए उच्च स्तर की विशेषज्ञता की आवश्यकता नहीं होती है। कोई भी AI/ML डेवलपर इसे कर सकता है। प्रत्येक एआई/एमएल डेवलपर को यह करना चाहिए।
हमने Intel® Xeon® प्रोसेसर पर ML अनुमान कार्यभार को अनुकूलित करने की चुनौती का समाधान किया। हमने कई परिदृश्यों की समीक्षा करके शुरुआत की, जिसमें एकाधिक समर्पित एआई अनुमान चिप्स के युग में भी एआई/एमएल अनुमान के लिए सीपीयू सबसे अच्छा विकल्प हो सकता है। फिर हमने एक खिलौना छवि-वर्गीकरण PyTorch मॉडल पेश किया और इसके रनटाइम प्रदर्शन को बढ़ाने के लिए कई तकनीकों का प्रदर्शन किया। Amazon EC2 c7i.xlarge उदाहरण, चौथी पीढ़ी के Intel Xeon स्केलेबल प्रोसेसर द्वारा संचालित। इस पोस्ट में, हम अपनी चर्चा को AWS के घरेलू आर्म-आधारित ग्रेविटॉन सीपीयू तक विस्तारित करते हैं। हम अपने पिछले पोस्टों में चर्चा किए गए कई अनुकूलन पर दोबारा गौर करेंगे – जिनमें से कुछ को आर्म प्रोसेसर में अनुकूलन की आवश्यकता होगी – और उसी खिलौना मॉडल पर उनके प्रभाव का आकलन करेंगे। आर्म और इंटेल प्रोसेसर के बीच गहरे अंतर को देखते हुए, सबसे अच्छा प्रदर्शन करने वाले कॉन्फ़िगरेशन के लिए रास्ते अलग-अलग हो सकते हैं।
एडब्ल्यूएस ग्रेविटॉन
एडब्ल्यूएस ग्रेविटॉन पर आधारित प्रोसेसरों का एक परिवार है आर्म नियोवर्स सीपीयू, जो इष्टतम मूल्य-प्रदर्शन और ऊर्जा दक्षता के लिए AWS द्वारा कस्टम डिज़ाइन और निर्मित किए गए हैं। वेक्टर प्रसंस्करण के लिए उनके समर्पित इंजन (नियोन और एसवीई/एसवीई2) और मैट्रिक्स गुणन (एमएमएलए), और उनके समर्थन के लिए बीफ्लोट16 ऑपरेशंस (ग्रेविटॉन 3 के रूप में), उन्हें गणना गहन कार्यभार चलाने के लिए एक आकर्षक उम्मीदवार बनाते हैं एआई/एमएल अनुमान. ग्रेविटॉन पर उच्च-प्रदर्शन एआई/एमएल की सुविधा के लिए, संपूर्ण सॉफ़्टवेयर स्टैक को इसके उपयोग के लिए अनुकूलित किया गया है:
- निम्न-स्तरीय कंप्यूट कर्नेल से आर्म कंप्यूट लाइब्रेरी (एसीएल) ग्रेविटॉन हार्डवेयर एक्सेलेरेटर (उदाहरण के लिए, एसवीई और एमएमएलए) का लाभ उठाने के लिए अत्यधिक अनुकूलित हैं।
- एमएल मिडलवेयर लाइब्रेरीज़ जैसे कि oneDNN और ओपनब्लास विशेष एसीएल कर्नेल के लिए गहन शिक्षण और रैखिक बीजगणित संचालन को रूट करें।
- एआई/एमएल फ्रेमवर्क पसंद पायटोरच और टेंसरफ़्लो इन अनुकूलित बैकएंड का उपयोग करने के लिए संकलित और कॉन्फ़िगर किया गया है।
इस पोस्ट में हम एक का प्रयोग करेंगे अमेज़न EC2 c8g.xlarge उदाहरण चार द्वारा संचालित एडब्ल्यूएस ग्रेविटॉन4 प्रोसेसर और एक AWS ARM64 PyTorch डीप लर्निंग AMI (DLAMI)।
इस पोस्ट का उद्देश्य AWS Graviton उदाहरण पर प्रदर्शन को बढ़ावा देने के लिए युक्तियाँ प्रदर्शित करना है। महत्वपूर्ण बात यह है कि हमारा इरादा है नहीं AWS Graviton और वैकल्पिक चिप्स के बीच तुलना करना, न ही यह एक चिप के दूसरे के उपयोग की वकालत करना है। प्रोसेसर का सबसे अच्छा विकल्प इस पोस्ट के दायरे से परे कई विचारों पर निर्भर करता है। महत्वपूर्ण विचारों में से एक प्रत्येक चिप पर आपके मॉडल का अधिकतम रनटाइम प्रदर्शन होगा। दूसरे शब्दों में: हम अपने पैसे के लिए कितना “धमाका” प्राप्त कर सकते हैं? इस प्रकार, सर्वोत्तम प्रोसेसर के बारे में एक सूचित निर्णय लेना प्रत्येक पर रनटाइम प्रदर्शन को अनुकूलित करने के लिए प्रेरणाओं में से एक है।
एकाधिक अनुमान उपकरणों के लिए हमारे मॉडल के प्रदर्शन को अनुकूलित करने के लिए एक और प्रेरणा, इसकी पोर्टेबिलिटी को बढ़ाना है। एआई/एमएल का खेल क्षेत्र बेहद गतिशील है और सफलता के लिए बदलती परिस्थितियों के प्रति लचीलापन महत्वपूर्ण है। कुछ प्रकार के गणना उदाहरणों का अचानक अनुपलब्ध या दुर्लभ हो जाना असामान्य नहीं है। इसके विपरीत, AWS Graviton उदाहरणों की क्षमता में वृद्धि, भारी छूट पर उनकी उपलब्धता का संकेत दे सकती है, उदाहरण के लिए, अमेज़न EC2 स्पॉट इंस्टेंस बाज़ार, लागत-बचत के अवसर प्रस्तुत कर रहा है जिन्हें आप चूकना नहीं चाहेंगे।
अस्वीकरण
कोड के ब्लॉक कोड जिन्हें हम साझा करेंगे, जिन अनुकूलन चरणों पर हम चर्चा करेंगे, और जिन परिणामों तक हम पहुंचेंगे, वे उन लाभों के उदाहरण के रूप में हैं जो आप एडब्ल्यूएस ग्रेविटॉन उदाहरण पर एमएल प्रदर्शन अनुकूलन से देख सकते हैं। ये आपके अपने मॉडल और रनटाइम परिवेश के साथ देखे जा सकने वाले परिणामों से काफी भिन्न हो सकते हैं। कृपया इस पोस्ट की सामग्री की सटीकता या इष्टतमता पर भरोसा न करें। कृपया किसी लाइब्रेरी, फ्रेमवर्क या प्लेटफ़ॉर्म के उल्लेख को उसके उपयोग के समर्थन के रूप में न समझें।
AWS Graviton पर अनुमान अनुकूलन
हमारी पिछली पोस्ट की तरह, हम खिलौना छवि वर्गीकरण मॉडल पर अनुकूलन चरणों का प्रदर्शन करेंगे:
import torch, torchvision
import time
def get_model(channels_last=False, compile=False):
model = torchvision.models.resnet50()
if channels_last:
model= model.to(memory_format=torch.channels_last)
model = model.eval()
if compile:
model = torch.compile(model)
return model
def get_input(batch_size, channels_last=False):
batch = torch.randn(batch_size, 3, 224, 224)
if channels_last:
batch = batch.to(memory_format=torch.channels_last)
return batch
def get_inference_fn(model, enable_amp=False):
def infer_fn(batch):
with torch.inference_mode(), torch.amp.autocast(
'cpu',
dtype=torch.bfloat16,
enabled=enable_amp
):
output = model(batch)
return output
return infer_fn
def benchmark(infer_fn, batch):
# warm-up
for _ in range(20):
_ = infer_fn(batch)
iters = 100
start = time.time()
for _ in range(iters):
_ = infer_fn(batch)
end = time.time()
return (end - start) / iters
batch_size = 1
model = get_model()
batch = get_input(batch_size)
infer_fn = get_inference_fn(model)
avg_time = benchmark(infer_fn, batch)
print(f"\nAverage samples per second: {(batch_size/avg_time):.2f}")प्रारंभिक थ्रूपुट 12 नमूने प्रति सेकंड (एसपीएस) है।
नवीनतम PyTorch रिलीज़ में अपग्रेड करें
जबकि हमारे DLAMI में PyTorch का संस्करण 2.8 है, इस लेखन के समय PyTorch का नवीनतम संस्करण 2.9 है। एआई/एमएल के क्षेत्र में विकास की तीव्र गति को देखते हुए, सबसे अद्यतित लाइब्रेरी पैकेजों का उपयोग करने की अत्यधिक अनुशंसा की जाती है। अपने पहले कदम के रूप में, हम अपग्रेड करते हैं पायटोरच 2.9 कौन इसके आर्म बैकएंड में प्रमुख अपडेट शामिल हैं.
pip3 install -U torch torchvision --index-url हमारे मॉडल के प्रारंभिक कॉन्फ़िगरेशन के मामले में, PyTorch संस्करण को अपग्रेड करने से कोई प्रभाव नहीं पड़ता है। हालाँकि, यह कदम उन अनुकूलन तकनीकों से अधिकतम लाभ प्राप्त करने के लिए महत्वपूर्ण है जिनका हम मूल्यांकन करेंगे।
बैचेड अनुमान
लॉन्चिंग ओवरहेड्स के ओवरहेड को कम करने और एचडब्ल्यू त्वरक के उपयोग को बढ़ाने के लिए, हम नमूनों को एक साथ समूहित करते हैं और बैच अनुमान लागू करते हैं। नीचे दी गई तालिका दर्शाती है कि बैच आकार के फ़ंक्शन के रूप में मॉडल थ्रूपुट कैसे भिन्न होता है:

मेमोरी अनुकूलन
हम मेमोरी आवंटन और उपयोग को अनुकूलित करने के लिए अपनी पिछली पोस्ट से कई तकनीकों को लागू करते हैं। इनमें शामिल हैं चैनल-अंतिम मेमोरी प्रारूप, स्वचालित मिश्रित परिशुद्धता Bfloat16 डेटा प्रकार (Graviton3 से समर्थित) के साथ टीसीमॉलोक आवंटन पुस्तकालय, और विशाल पृष्ठ आवंटन। विवरण के लिए कृपया देखें. हम भी सक्षम करते हैं तेज़ गणित ACL GEMM कर्नेल का मोड, और कर्नेल प्राइमेटिव्स की कैशिंग – दो अनुकूलन जो आधिकारिक में दिखाई देते हैं Graviton पर PyTorch अनुमान चलाने के लिए दिशानिर्देश.
इन अनुकूलनों को सक्षम करने के लिए आवश्यक कमांड लाइन निर्देश नीचे दिखाए गए हैं:
# install TCMalloc
sudo apt-get install google-perftools
# Program the use of TCMalloc
export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libtcmalloc.so.4
# Enable huge page memory allocation
export THP_MEM_ALLOC_ENABLE=1
# Enable the fast math mode of the GEMM kernels
export DNNL_DEFAULT_FPMATH_MODE=BF16
# Set LRU Cache capacity to cache the kernel primitives
export LRU_CACHE_CAPACITY=1024निम्न तालिका क्रमिक रूप से लागू किए गए मेमोरी अनुकूलन के प्रभाव को दर्शाती है:

हमारे खिलौना मॉडल के मामले में, चैनल-अंतिम और bfloat16-मिश्रित परिशुद्धता अनुकूलन का सबसे अधिक प्रभाव पड़ा। सभी मेमोरी अनुकूलन लागू करने के बाद, औसत थ्रूपुट 53.03 एसपीएस है।
मॉडल संकलन
AWS Graviton के लिए PyTorch संकलन का समर्थन एक है AWS Graviton टीम के केंद्रित प्रयास का क्षेत्र. हालाँकि, हमारे खिलौना मॉडल के मामले में, इसके परिणामस्वरूप 53.03 एसपीएस से 52.23 तक थ्रूपुट में थोड़ी कमी आती है।
बहु-कार्यकर्ता अनुमान
जबकि आम तौर पर चार से अधिक वीसीपीयू के साथ सेटिंग्स में लागू किया जाता है, हम कोर पिनिंग का समर्थन करने के लिए अपनी स्क्रिप्ट को संशोधित करके मल्टी-वर्कर अनुमान के कार्यान्वयन को प्रदर्शित करते हैं:
if __name__ == '__main__':
# pin CPUs according to worker rank
import os, psutil
rank = int(os.environ.get('RANK','0'))
world_size = int(os.environ.get('WORLD_SIZE','1'))
cores = list(range(psutil.cpu_count(logical=True)))
num_cores = len(cores)
cores_per_process = num_cores // world_size
start_index = rank * cores_per_process
end_index = (rank + 1) * cores_per_process
pid = os.getpid()
p = psutil.Process(pid)
p.cpu_affinity(cores(start_index:end_index))
batch_size = 8
model = get_model(channels_last=True)
batch = get_input(batch_size, channels_last=True)
infer_fn = get_inference_fn(model, enable_amp=True)
avg_time = benchmark(infer_fn, batch)
print(f"\nAverage samples per second: {(batch_size/avg_time):.2f}")हम ध्यान दें कि अन्य AWS EC2 CPU इंस्टेंस प्रकारों के विपरीत, प्रत्येक Graviton vCPU सीधे एकल भौतिक CPU कोर पर मैप करता है। हम उपयोग करते हैं मशाल दौड़ चार कर्मचारियों को शुरू करने की उपयोगिता, जिनमें से प्रत्येक एक ही सीपीयू कोर पर चल रहा है:
export OMP_NUM_THREADS=1 #set one OpenMP thread per worker
torchrun --nproc_per_node=4 main.pyइसका परिणाम 55.15 एसपीएस का थ्रूपुट है, जो हमारे पिछले सर्वोत्तम परिणाम से 4% सुधार है।
आर्म के लिए INT8 परिमाणीकरण
आर्म पर सक्रिय विकास और निरंतर सुधार का एक अन्य क्षेत्र INT8 परिमाणीकरण है। INT8 परिमाणीकरण उपकरण आम तौर पर लक्ष्य उदाहरण प्रकार से काफी हद तक बंधे होते हैं। हमारी पिछली पोस्ट में हमने प्रदर्शित किया था Inductor के माध्यम से X86 बैकएंड के साथ PyTorch 2 निर्यात क्वांटाइजेशन का उपयोग टॉर्चएओ (0.12.1) पुस्तकालय। सौभाग्य से, के नवीनतम संस्करण टॉर्चएओ एक समर्पित शामिल करें आर्म के लिए क्वांटाइज़र. अद्यतन परिमाणीकरण अनुक्रम नीचे दिखाया गया है। जैसा कि हमारी पिछली पोस्ट में था, हम केवल संभावित प्रदर्शन प्रभाव में रुचि रखते हैं। व्यवहार में, INT8 परिमाणीकरण मॉडल की गुणवत्ता पर महत्वपूर्ण प्रभाव डाल सकता है और अधिक परिष्कृत परिमाणीकरण रणनीति की आवश्यकता हो सकती है।
from torchao.quantization.pt2e.quantize_pt2e import prepare_pt2e, convert_pt2e
import torchao.quantization.pt2e.quantizer.arm_inductor_quantizer as aiq
def quantize_model(model):
x = torch.randn(4, 3, 224, 224).contiguous(
memory_format=torch.channels_last)
example_inputs = (x,)
batch_dim = torch.export.Dim("batch")
with torch.no_grad():
exported_model = torch.export.export(
model,
example_inputs,
dynamic_shapes=((batch_dim,
torch.export.Dim.STATIC,
torch.export.Dim.STATIC,
torch.export.Dim.STATIC),
)
).module()
quantizer = aiq.ArmInductorQuantizer()
quantizer.set_global(aiq.get_default_arm_inductor_quantization_config())
prepared_model = prepare_pt2e(exported_model, quantizer)
prepared_model(*example_inputs)
converted_model = convert_pt2e(prepared_model)
optimized_model = torch.compile(converted_model)
return optimized_model
batch_size = 8
model = get_model(channels_last=True)
model = quantize_model(model)
batch = get_input(batch_size, channels_last=True)
infer_fn = get_inference_fn(model, enable_amp=True)
avg_time = benchmark(infer_fn, batch)
print(f"\nAverage samples per second: {(batch_size/avg_time):.2f}")परिणामी थ्रूपुट bfloat16 समाधान पर 7.1% सुधार के लिए 56.77 एसपीएस है।
ONNX और OpenVINO का उपयोग करके AOT संकलन
हमारी पिछली पोस्ट में, हमने समय से पहले (एओटी) मॉडल संकलन तकनीकों का उपयोग करके पता लगाया न्यूरल नेटवर्क एक्सचेंज खोलें (ओएनएनएक्स) और ओपनविनो. दोनों पुस्तकालयों में AWS Graviton पर चलने के लिए समर्पित समर्थन शामिल है (उदाहरण के लिए, देखें)। यहाँ और यहाँ). इस खंड के प्रयोगों के लिए निम्नलिखित पुस्तकालय स्थापनाओं की आवश्यकता है:
pip install onnxruntime onnxscript openvino nncfनिम्नलिखित कोड ब्लॉक ONNX का उपयोग करके आर्म पर मॉडल संकलन और निष्पादन को प्रदर्शित करता है:
def export_to_onnx(model, onnx_path="resnet50.onnx"):
dummy_input = torch.randn(4, 3, 224, 224)
batch = torch.export.Dim("batch")
torch.onnx.export(
model,
dummy_input,
onnx_path,
input_names=("input"),
output_names=("output"),
dynamic_shapes=((batch,
torch.export.Dim.STATIC,
torch.export.Dim.STATIC,
torch.export.Dim.STATIC),
),
dynamo=True
)
return onnx_path
def onnx_infer_fn(onnx_path):
import onnxruntime as ort
sess = ort.InferenceSession(
onnx_path,
providers=("CPUExecutionProvider")
)
sess_options = ort.SessionOptions()
sess_options.add_session_config_entry(
"mlas.enable_gemm_fastmath_arm64_bfloat16", "1")
input_name = sess.get_inputs()(0).name
def infer_fn(batch):
result = sess.run(None, {input_name: batch})
return result
return infer_fn
batch_size = 8
model = get_model()
onnx_path = export_to_onnx(model)
batch = get_input(batch_size).numpy()
infer_fn = onnx_infer_fn(onnx_path)
avg_time = benchmark(infer_fn, batch)
print(f"\nAverage samples per second: {(batch_size/avg_time):.2f}")यह ध्यान दिया जाना चाहिए कि ONNX रनटाइम एक समर्पित का समर्थन करता है एसीएल-निष्पादन प्रदाता आर्म पर चलने के लिए, लेकिन इसके लिए एक कस्टम ONNX बिल्ड की आवश्यकता होती है (इस लेखन के समय तक), जो इस पोस्ट के दायरे से बाहर है।
वैकल्पिक रूप से, हम इसका उपयोग करके मॉडल संकलित कर सकते हैं ओपनविनो. नीचे दिया गया कोड ब्लॉक इसके उपयोग को दर्शाता है, जिसमें INT8 परिमाणीकरण के उपयोग का विकल्प भी शामिल है एनएनसीएफ:
import openvino as ov
import nncf
def openvino_infer_fn(compiled_model):
def infer_fn(batch):
result = compiled_model((batch))(0)
return result
return infer_fn
clblock RandomDataset(torch.utils.data.Dataset):
def __len__(self):
return 10000
def __getitem__(self, idx):
return torch.randn(3, 224, 224)
quantize_model = False
batch_size = 8
model = get_model()
calibration_loader = torch.utils.data.DataLoader(RandomDataset())
calibration_dataset = nncf.Dataset(calibration_loader)
if quantize_model:
# quantize PyTorch model
model = nncf.quantize(model, calibration_dataset)
ovm = ov.convert_model(model, example_input=torch.randn(1, 3, 224, 224))
ovm = ov.compile_model(ovm)
batch = get_input(batch_size).numpy()
infer_fn = openvino_infer_fn(ovm)
avg_time = benchmark(infer_fn, batch)
print(f"\nAverage samples per second: {(batch_size/avg_time):.2f}")हमारे खिलौना मॉडल के मामले में, ओपनविनो संकलन के परिणामस्वरूप थ्रूपुट में 63.48 एसपीएस की अतिरिक्त वृद्धि होती है, लेकिन एनएनसीएफ परिमाणीकरण निराश करता है, जिसके परिणामस्वरूप केवल 55.18 एसपीएस होता है।
परिणाम
हमारे प्रयोगों के परिणाम नीचे दी गई तालिका में संक्षेपित हैं:

जैसा कि हमारे में है, हमने अपने प्रयोगों को दूसरे मॉडल – एक विज़न ट्रांसफॉर्मर (वीआईटी) पर दोबारा चलाया टिम लाइब्रेरी – यह प्रदर्शित करने के लिए कि जिस रनटाइम अनुकूलन पर हमने चर्चा की उसका प्रभाव मॉडल के विवरण के आधार पर कैसे भिन्न हो सकता है। परिणाम नीचे दिए गए हैं:

सारांश
इस पोस्ट में, हमने कई अपेक्षाकृत सरल अनुकूलन तकनीकों की समीक्षा की और उन्हें दो खिलौना PyTorch मॉडल पर लागू किया। जैसा कि परिणाम प्रदर्शित करते हैं, प्रत्येक अनुकूलन चरण का प्रभाव मॉडल के विवरण के आधार पर काफी भिन्न हो सकता है, और चरम प्रदर्शन की ओर यात्रा कई अलग-अलग रास्ते ले सकती है। इस पोस्ट में हमने जो कदम प्रस्तुत किए वे सिर्फ एक क्षुधावर्धक थे; निस्संदेह कई और अनुकूलन हैं जो और भी बेहतर प्रदर्शन को अनलॉक कर सकते हैं।
रास्ते में, हमने कई एआई/एमएल पुस्तकालयों पर ध्यान दिया, जिन्होंने ग्रेविटॉन आर्किटेक्चर के लिए गहरा समर्थन पेश किया है, और चल रहे अनुकूलन के निरंतर सामुदायिक प्रयास भी पेश किए हैं। इस स्पष्ट समर्पण के साथ मिलकर हमने जो प्रदर्शन लाभ हासिल किया है, वह साबित करता है कि जब गणना-गहन एआई/एमएल वर्कलोड चलाने की बात आती है तो एडब्ल्यूएस ग्रेविटॉन दृढ़ता से “बड़ी लीग” में है।
(टैग्सटूट्रांसलेट)आर्टिफिशियल इंटेलिजेंस(टी)डीप लर्निंग(टी)इंफेरेंस(टी)मशीन लर्निंग(टी)पाइटोरच
Latest Technology, (लेटेस्ट टेक न्यूज़) Gadget (गैजेट्स) …
Source link
