2 पॉइंट द्वारा GN⁺ 2024-05-10 | 2 टिप्पणियां | WhatsApp पर शेयर करें
  • Hacker News की सार्वजनिक API से 4 करोड़ से ज़्यादा items इकट्ठा करके, 3 करोड़ से ज़्यादा comments और 40 लाख posts में embeddings, metadata और body text जोड़ने वाला यह एक search, map और analysis project है
  • शुरुआती तरीका, जिसमें केवल title embed किया जाता था, अस्पष्ट titles और Ask HN/Show HN bias की वजह से सीमित था; बाद में linked webpages के body text, top comments और comments के ancestor context को साथ इस्तेमाल करने की रणनीति अपनाई गई
  • processing scale बढ़ने पर RunPod के लगभग 150 GPUs, Rust queue service, HTTP/2 DB proxy, UMAP, Canvas rendering और edge servers को मिलाकर इस्तेमाल किया गया; model बदलने के बाद प्रति input embedding time लगभग 600ms से घटकर 6ms हो गया
  • search ranking simple string match नहीं है; इसमें cosine similarity, HN score और time weighting को साथ इस्तेमाल कर semantic relevance, social signals और freshness को reflect किया जाता है
  • public demo में केवल लगभग 10 अप्रैल 2024 तक का data शामिल है; पूरा data और code GitHub पर public हैं, जिन्हें search, recommendations, user analysis और real-time update experiments में इस्तेमाल किया जा सकता है

Project scope और public data

  • Hacker News की सभी posts को semantic space में रखने वाला map बनाया गया, और साथ में search, analysis और visualization tools भी बनाए गए
  • शुरुआत text embedding experiments से हुई थी; HN में curated content काफी है और वह सारा content programmatic तरीके से उपलब्ध कराता है, इसलिए इसे suitable dataset के रूप में चुना गया
  • embeddings text को high-dimensional space में points के रूप में represent करते हैं; absolute position से ज़्यादा points के बीच की relative distance उपयोगी होती है
  • अपेक्षित उपयोग तीन थे
    • HN के जमा हुए content में meaning-based search
    • interest areas के हिसाब से personalized recommendations
    • community के भीतर topics के हिसाब से sentiment, popularity और opposing viewpoints का analysis
  • 3 करोड़ से ज़्यादा comments और 40 लाख posts dataset release के रूप में public किए गए
    • ID, score, author जैसे metadata शामिल
    • embeddings शामिल
    • comment text और crawled webpage text शामिल
  • code hackerverse GitHub repository में public है

Hacker News data collection

  • HN एक simple public API देता है, और हर object को item के रूप में query किया जाता है
  • maxitem.json सबसे बड़ा ID देता है, और लिखे जाने के समय maximum ID 4 करोड़ से अधिक था
  • average response time 10ms भी हो, तो 4 करोड़ items को sequentially crawl करने में 4 दिन से ज़्यादा लगेंगे, इसलिए parallel processing की ज़रूरत थी
  • Node.js से fast collection service बनाई गई, लेकिन semaphore और Promise queue approach में CPU time का ज़्यादातर हिस्सा user-space JS code में खर्च हो रहा था, इसलिए यह धीमा था
  • बाद में worker_threads API से fetch tasks को सभी CPUs में distribute किया गया, और सभी cores को saturate करने के तरीके से performance बेहतर हुई
  • parallel collection में order गड़बड़ा जाता है, इसलिए interruption पर missing data न हो, इसके लिए completion markers को ID order में record किया गया
  • HN API में कुछ खास बातें भी देखी गईं
    • score -1 से नीचे नहीं जाता दिखता
    • posts के downvotes और comments के vote count को fetch नहीं किया जा सकता
    • कुछ posts और comments deleted या flagged न होने पर भी title, text और URL खाली होते हैं
    • comment ID अपने ancestors से छोटा हो सकता है, शायद comment tree movement की वजह से
  • HN crawler को अलग TypeScript project crawler-toolkit-hn के रूप में भी अलग किया गया

पहली embedding और infrastructure

  • शुरुआत में माना गया कि केवल post title से भी semantic representation पर्याप्त होगा, और embeddings बनाए गए
  • model comparison के लिए Massive Text Embedding Benchmark देखा गया, और शुरू में चुना गया model BGE-M3 था
  • BGE-M3 common dense embeddings के अलावा lexical weights भी बना सकता है, इसलिए इसे BM25 जैसे methods के साथ hybrid search में इस्तेमाल किया जा सकता है
  • embedding generation infrastructure simple नहीं था
    • अच्छे models में करोड़ों से अरबों parameters हो सकते हैं
    • GPU पर ये कहीं ज़्यादा efficient होते हैं, लेकिन GPU clusters महंगे होते हैं
    • अगर inference प्रति input सैकड़ों ms ले, तो single GPU से 4 करोड़ inputs process करना लगभग एक साल के scale का काम हो जाता है
    • data, servers और GPUs अलग-अलग जगह होने के कारण pipeline को ऐसा बनाए रखना पड़ता है कि GPUs idle न रहें
  • RunPod का इस्तेमाल कर datacenter में चलने वाली GPU machines को containers के रूप में deploy किया गया, और RTX 4090 जैसे अपेक्षाकृत सस्ते GPUs का उपयोग किया गया
  • GPUs दुनिया भर में फैले होने से DB connection latency और connection overhead problem बन गए, इसलिए db-rpc बनाया गया
    • SQL queries को HTTP/2 से local DB पर proxy करता है
    • बड़ा shared connection pool इस्तेमाल करता है
    • HTTP/2 multiplexing से single connection पर कई queries process करता है
  • AWS SQS में लाखों छोटे task messages के लिए low rate limits और per-message cost भारी पड़ रही थी, इसलिए RocksDB-based Rust queue service queued बनाया गया
    • single node पर 100K+ op/s handle करता है
    • batching, message size, rate limits और cost burden को कम करता है
  • लगभग 150 GPUs तक scale करने के परिणामस्वरूप, 4 करोड़ posts और comments को कुछ ही घंटों में embed कर दिया गया
  • उस समय प्रति input embedding cost लगभग 600ms थी, और पूरे समय GPU utilization high बनी रही

Webpage crawling से context मजबूत करना

  • केवल title embed करने का तरीका पर्याप्त नहीं था
    • कई posts के titles अजीब, creative या ambiguous होते हैं
    • Ask HN और Show HN phrases title में बड़ा हिस्सा ले लेते थे, जिससे वे topic से असंबंधित होकर भी साथ cluster होने लगते थे
  • text posts और comments के लिए उनका अपना text इस्तेमाल किया जा सकता था, लेकिन अधिकांश link posts के लिए linked webpage crawl करना ज़रूरी था
  • Rust service से URLs fetch किए गए और HTML से title, image, author, body text जैसे metadata parse किए गए
  • शुरुआती Node.js version CPU-intensive tasks में Rust version से 10 गुना धीमा था, और Rust rewrite से performance बेहतर हुई
  • text extraction में scraper से HTML parse किया गया, semantic रूप से main content न माने जाने वाले HTML5 elements हटाए गए, फिर बचे हुए tree को traverse किया गया
  • link rot भी बड़ा issue था
    • लगभग 2 लाख URLs 404, DNS lookup failure या connection timeout से fail हुए
    • यह 40 लाख pages में 5% से कम है
  • missing data घटाने के लिए Internet Archive के Wayback API से कुछ पुराने articles लाए गए
    • Internet Archive की rate limit बहुत कम, लगभग 5 requests प्रति minute के स्तर पर थी

दूसरी embedding strategy

  • webpages लंबे होते हैं, लेकिन BGE-M3 8192-token context window support करता है
  • हालांकि BGE-M3 धीमा था, इसलिए इसे jina-embeddings-v2-small-en से replace किया गया
    • parameters की संख्या काफी कम है
    • MTEB के हिसाब से performance भी अच्छी है
    • inference time लगभग 6ms तक घट गया, यानी 100 गुना तेज़
  • लंबे inputs के कारण batch size बढ़ाने पर OOM हो जाता था, इसलिए GPU पूरी तरह saturate नहीं हो पाता था
  • जिन pages में text कम था या जिन्हें fetch नहीं किया जा सका, उन्हें supplement करने के लिए post के top HN comments को body के पीछे जोड़ा गया
    • top-level comments के लिए माना गया कि item.kids पहले से ranked है
    • deleted, dead और negative-score comments हटाए गए
    • input को maximum 64KiB तक सीमित किया गया
  • comments अकेले meaningful context में कम पड़ सकते हैं, इसलिए ancestor comments और post title तक पीछे जाकर लंबा context बनाया गया
  • embeddings और text जैसे बड़े values को अलग kv table में store किया गया
    • row में साथ store करने पर row बहुत भारी हो जाती है
    • छोटे column updates भी महंगे हो जाते हैं
    • schema changes भी महंगे हो जाते हैं

UMAP से 2D semantic map बनाना

  • UMAP एक dimension reduction तकनीक है, जो high-dimensional embeddings को कम dimensions में घटाते हुए semantic relationships को बचाए रखने की कोशिश करती है
  • 1024-dimensional embedding vectors को 2D points में घटाकर scatter plot और map visualization में इस्तेमाल किया गया
  • UMAP ने PyNNDescent graph और original embeddings को input के रूप में लिया, और metric="cosine", n_components=2 का उपयोग किया गया
  • लाखों high-dimensional inputs पर training में समय लगता है, इसलिए EC2 के c7i.metal-48xl VM का इस्तेमाल किया गया
    • 96-core processor का पूरा उपयोग किया गया
    • करीब 1 घंटा 30 मिनट बाद 2D matrix बनी
  • बनी हुई 2D embeddings और trained UMAP model को save किया गया, ताकि बाद में नई embeddings को भी retraining के बिना transform किया जा सके
  • शुरुआती scatter plot में points बहुत ज़्यादा थे, इसलिए grid cell के हिसाब से सबसे high-score posts ही चुनी गईं और density घटाकर titles दिखाए गए
  • ज़्यादा context डालने वाली दूसरी embedding में, जिन posts को सिर्फ title से समझना मुश्किल था, वे संबंधित content के पास ज़्यादा सटीक तरह से रखी गईं

Cosine similarity और search ranking

  • embeddings के उपयोग का मूल उद्देश्य दो embeddings के बीच similarity निकालना है
  • text embeddings में सामान्य Euclidean distance की तुलना में cosine distance/similarity का ज़्यादा इस्तेमाल होता है
  • cosine distance उन मामलों में उपयोगी है जहाँ magnitude से ज़्यादा direction मायने रखती है
    • X से जुड़ी लंबी discussion को Y से जुड़ी लंबी discussion की तुलना में X के ज़्यादा समान होना चाहिए
    • magnitude को शामिल करने पर ऐसे relationships गलत दिशा में जा सकते हैं
  • इस्तेमाल की गई मुख्य calculation embedding matrix और query embedding का dot product थी
  • अगर vectors unit vectors हों, तो अलग से magnitude से divide करने की ज़रूरत नहीं होती
  • search results को सिर्फ pure similarity के आधार पर sort नहीं किया गया
    • cosine similarity एक बड़ा factor है, लेकिन अकेला factor नहीं है
    • HN score को social proof के रूप में इस्तेमाल किया गया
    • time weight को log(age) के proportional negative factor के रूप में शामिल किया गया, ताकि freshness important होने वाली queries में पुराना content जल्दी नीचे चला जाए

Browser map app

  • लक्ष्य HN embedding space को Google Maps की तरह explore करने योग्य interactive map बनाना था
  • अपेक्षित behavior स्पष्ट था
    • pinch या mouse wheel से zoom करने पर और points दिखाई दें
    • points के बीच की दूरी भी बढ़े
    • कुछ points पर labels लगें, लेकिन सभी पर नहीं
    • point पर click करने से post details दिखें
    • mobile और desktop पर touch और mouse दोनों support हों
  • लाखों points होने की वजह से सभी points को एक साथ client को भेजना उपयुक्त नहीं था
  • map space को grid tiles में बाँटकर, client द्वारा केवल ज़रूरी tiles fetch करने वाला structure इस्तेमाल किया गया
    • tiles को (x, y) coordinates से identify किया जा सकता है
    • इन्हें S3 जैसे KV storage में save किया जा सकता है
    • server-side logic के बिना deploy करना आसान है
  • zoom levels को LOD तरीके से handle किया गया
    • हर level पर प्रत्येक axis को 2 गुना ज़्यादा grid cells में बाँटा गया
    • पिछले level पर चुने गए points को अगले level में भी copy किया गया, ताकि zoom करते समय points गायब न हों
  • tile size के लिए compression के बाद 20KiB से कम का लक्ष्य रखा गया
    • इसे लगभग 1,500 points तक सीमित किया गया
    • हर point के लिए (x, y) 8 bytes, ID 4 bytes, score 2 bytes इस्तेमाल किए गए
  • web app rendering में हजारों DOM elements वाला तरीका performance को बहुत खराब कर रहा था
  • final implementation ने Canvas का उपयोग किया और viewport update होने पर हर बार redraw करने का तरीका अपनाया
    • हर frame में हजारों points redraw करने पर भी यह smooth और simple चलता है
  • labeling में highest-score posts को बार-बार चुना गया, लेकिन अगर वे मौजूदा labels से overlap करते थे तो exclude किया गया
    • collision check के लिए RBush R-tree implementation का इस्तेमाल किया गया
    • label length को browser measureText() के बजाय title-length byte array और adjusted formula से approximate किया गया
  • initial label boxes और collision calculation CPU-intensive थे, इसलिए उन्हें Web Workers में ले जाया गया
  • OffscreenCanvas भी experiment किया गया, लेकिन rendering logic पहले से efficient था, इसलिए बड़ा असर नहीं दिखा

Terrain, boundaries और city labels

  • map में केवल points होने पर direction का एहसास और visual interest कम था, इसलिए terrain और cities की अवधारणा जोड़ी गई
  • असली geography या political boundaries नहीं थीं, इसलिए terrain को point density दिखाने के रूप में metaphor की तरह इस्तेमाल किया गया
  • point density को activity, interest, content, participation, popularity और discussion-heavy areas जल्दी दिखाने वाले signal के रूप में इस्तेमाल किया गया
  • शुरुआत में Kernel Density Estimation पर विचार किया गया, लेकिन standard libraries के trials में बहुत ज़्यादा समय लगा
  • इसके बजाय हर point को बड़े grid cell में map किया गया, per-cell count बनाया गया, और फिर Gaussian blur apply किया गया
  • linear density values में ज़्यादातर हिस्से 0 के करीब दिखते थे, जिससे map अच्छा नहीं लग रहा था
  • log(density + 1) apply करने पर कहीं ज़्यादा natural hierarchy बनी, और अलग-अलग density levels जहाँ मिलते थे, वे implicit boundaries जैसे दिखे
  • बड़ी image के बजाय SVG paths बनाए गए, ताकि client पर polygons के रूप में draw किया जा सके
    • सिर्फ 4 colors होने से यह efficient था
    • zoom करने पर भी boundaries sharp रहती हैं
    • OpenCV के contour function से हर level के closed curves calculate किए गए
  • city labels किसी खास radius के भीतर common topic को दिखाते हैं
  • city names को embed करने के बाद saved UMAP model से उनकी (x, y) position निकाली गई
  • automatic generation भी try किया गया
    • LLM से city names बनवाने की कोशिश की गई, लेकिन prompt से desired output reliably पाना मुश्किल था
    • K-means कई ऐसे meaningful clusters नहीं खोज पाया जिन्हें इंसान स्वाभाविक रूप से group करता
  • अंत में map को खुद explore करते हुए कुछ cities manual रूप से लिखी गईं, जिसमें करीब 1 घंटा लगा

Edge deployment और responsiveness

  • map exploration को fast और responsive होना चाहिए, इसलिए data fetch latency घटाना important था
  • शुरुआत में सभी map data को Cloudflare R2 के ENAM region में रखा गया था, लेकिन latency 600ms से कई seconds तक आ रही थी
  • physical latency करीब 200ms होने पर भी, 100ms को instant response जैसा महसूस होने की threshold मानें तो यह पर्याप्त अच्छा नहीं था
  • latency घटाने के लिए data को users के करीब ले जाया गया
  • Virginia, San Jose, London और Sydney में छोटे servers रखे गए और Rust server से data serve किया गया
  • client कई edge servers के /healthz को कुछ बार call करता है और जो server सबसे पहले response देता है उसे चुनता है
  • Anycast या CDN जैसे तरीके भी संभव थे, लेकिन cost और जरूरत से ज़्यादा complexity के कारण इस्तेमाल नहीं किए गए
  • edge server process की memory usage original data से 2–4 गुना बड़ी थी, जिससे सवाल बाकी रहा
    • गलत type इस्तेमाल होने की संभावना
    • struct padding
    • Vec, HashMap की over-allocation
    • memory allocator fragmentation या inefficiency की संभावना

Semantic search results और सीमाएँ

  • “entering the tech industry” जैसी simple query में ज़्यादा upvotes वाले results और कम ध्यान पाए results साथ में दिखे, और relevance व usefulness अच्छी लगी
  • HN की मौजूदा search service से तुलना करें तो semantic embedding search exact text match न होने पर भी results ढूंढ लेती है
  • “what happened to wework” जैसी question-style query भी WeWork की layoffs, stock decline, bankruptcy आदि से जुड़े कई वर्षों में फैले results दिखाती है
  • search results में “what happened” शब्द सच में शामिल न हों या वे question format में न हों, फिर भी matching होती है
  • एक समस्या यह थी कि बहुत कम similar results को filter नहीं किया गया, जिससे पूरी तरह irrelevant lower results भी शामिल हो गए
    • इसे आसानी से fix होने वाली समस्या माना गया
  • “career growth” search में ऐसे creative और diverse essays दिखे जिनमें ये शब्द exact रूप से शामिल नहीं थे
  • HN की curation quality और scores search quality में मदद करते हैं
  • app में “linus rants”, “self bootstrapping”, “cool things with css” जैसी query suggestions hardcoded हैं

वर्चुअल कम्युनिटी और कमेंट विश्लेषण

  • embeddings का उपयोग करके वर्चुअल subcommunity फीचर बनाया जा सकता है
  • जब यूज़र कम्युनिटी का नाम या विवरण डालता है, तो एक तय similarity threshold से ऊपर की पोस्ट तुरंत एक साथ grouped हो जाती हैं
  • HN में पोस्ट को और granular तरीके से बाँटने का फीचर नहीं है, इसलिए यह किसी खास रुचि-केंद्रित curation को तुरंत बनाने का तरीका है
  • रिज़ल्ट कार्ड के snippets और images वेब crawler द्वारा सेव किए गए page metadata से लिए जाते हैं
  • site icon को जटिल metadata parsing के बजाय client-side पर domain के /favicon.ico को लाने के तरीके से सरल बनाया गया
  • comment threads को भी इसी तरीके से दिखाया जा सकता है
  • comment score HN API में उपलब्ध नहीं होता, इसलिए केवल chronological sorting संभव है
  • comment score के बिना ranking करने के तरीके के रूप में user comment history, उस comment के आसपास engagement, post, topic, content आदि का उपयोग संभव माना गया
  • किसी खास topic में प्रभावशाली या सक्रिय users को ढूँढना भी संभव है
    • “cloudflare” query में jgrahamc और eastdakota ऊपर दिखाई देते हैं
    • दोनों users क्रमशः Cloudflare के CTO और CEO हैं
  • यह काम comments को अलग से classify किए बिना या keyword search इस्तेमाल किए बिना, matrix operations से प्रोसेस होता है
  • pre-filtering की तुलना में post-filtering आम तौर पर तेज और पर्याप्त होती है
    • pre-filtering में embedding matrix से संबंधित rows हटानी पड़ती हैं, जिसके लिए विशाल memory copy या धीमी partial vectorized calculation की जरूरत हो सकती है
    • बेहतर यही माना गया कि पहले similar rows ढूँढी जाएँ और फिर results को filter किया जाए
  • minimum threshold महत्वपूर्ण है
    • गैर-संबंधित items में भी similarity लगभग 0.6 हो सकती है
    • threshold न हो तो बहुत अधिक comments वाले users केवल scale की वजह से ranking पर हावी हो सकते हैं

पूरे comment data का sentiment और popularity विश्लेषण

  • 3 करोड़ comments पर जो large-scale analysis करना चाहा गया था, वह popularity और sentiment था
  • लक्ष्य यह देखना था कि HN समय के साथ किसी खास topic को कैसे महसूस करता है, प्रमुख events sentiment को कैसे प्रभावित करते हैं, और रुचि वाले topics कैसे बढ़ते-घटते हैं
  • sentiment data उपलब्ध नहीं था, इसलिए Hugging Face का open-source sentiment classification model इस्तेमाल किया गया
  • चुना गया model TweetEval था, जो social media content पर trained model है
  • TweetEval छोटे tweets के लिए model है, इसलिए embeddings की तरह ancestor context जोड़े बिना केवल comment itself को input के रूप में इस्तेमाल किया गया
  • comments को queue में डालकर GPU cluster पर jobs प्रोसेस किए गए और फिर results save किए गए
  • model छोटा था, इसलिए batch size बढ़ाकर GPU efficiency बढ़ाई गई
  • batch size बढ़ाने से VRAM ज्यादा इस्तेमाल होती है, लेकिन host-GPU memory transfer घटता है और parallelism बढ़ सकता है
  • Transformer models में batch input rectangular होना चाहिए, इसलिए सबसे लंबे input length के हिसाब से padding की जाती है
    • अगर कुछ छोटे inputs के साथ एक लंबा input मिल जाए, तो पूरा input size और internal state काफी बढ़ सकता है
    • इसी वजह से memory spikes और OOM हो सकते हैं
  • Rust sentiment analysis example में Rust के लिए positive sentiment कुल मिलाकर ज्यादा था
    • Rust 1.0 announcement के आसपास positive spike था
    • ज्यादा negative posts model के हिसाब से बड़ी संख्या में negative comments से correlated थीं
  • भाषा-वार popularity भी score और similarity को weight करके estimate की गई
    • HN comment scores उपलब्ध नहीं कराता, इसलिए comment scores इस्तेमाल नहीं किए जा सकते
    • Rust अच्छा कर रहा है, लेकिन यह दूसरी languages जितना popular नहीं दिखा
    • similarity threshold को tune करने की जरूरत हो सकती है, इसलिए results गलत हो सकते हैं

GPU से बड़े पैमाने की numerical calculation को accelerate करना

  • analysis queries को 32-core machine पर भी 10–30 seconds लगते थे, जो interactive experiments के लिए धीमा था
  • index या preprocessing पर विचार करते हुए, vectorized numerical calculation के लिए GPU इस्तेमाल करने के तरीके पर switch किया गया
  • CuPy और cuDF क्रमशः NumPy और pandas जैसे API देते हैं, लेकिन GPU पर run होते हैं
  • porting अपेक्षाकृत आसान थी, और query time घटकर कुछ सौ ms के स्तर पर आ गया
  • speed पर्याप्त तेज थी, इसलिए ANN graph भी इस्तेमाल नहीं किया गया
  • मुश्किल हिस्सा बड़ी embedding matrix को GPU पर लोड करना था
    • comment embedding matrix का size 30M x 512 है
    • system memory या video memory में matrix की 1x से अधिक copy रखना मुश्किल था
  • simple loading approach कई copies बना सकती है
    • disk से bytes पढ़ना
    • NumPy array में load करना
    • CuPy array में convert करना
    • GPU पर copy करना
    • इस process में कुल 4 copies बन सकती हैं, जिनमें से 3 memory में होती हैं
  • अंतिम तरीका यह था कि disk पर मौजूद matrix को memory-map किया जाए, GPU पर उसी size की uninitialized matrix पहले से allocate की जाए, और फिर chunks में copy किया जाए
  • यह तरीका पहले Python memory में पढ़ने से बचाता है, और system RAM तथा VRAM में प्रत्येक में ठीक 1x ही उपयोग करता है

Demo और अगले कदम

  • demo app hn.wilsonl.in पर उपलब्ध है
  • main page map और search है, और top-right button से communities और analysis tools तक पहुँचा जा सकता है
  • community या analysis results के URL query को URL में save करते हैं, इसलिए उन्हें दूसरों के साथ share किया जा सकता है
  • demo dataset लगभग 10 अप्रैल 2024 के आसपास तक सीमित है, और इसमें latest live posts और comments शामिल नहीं हैं
  • आगे explore करने के लिए कई ideas हैं
    • लगातार up-to-date रहने वाला live data
    • HN के curated web के ऊपर काम करने वाला deep learning-based recommendation system
    • reranker training के जरिए search results में सुधार
    • map पर दिलचस्प paths और journeys
    • users के बीच similar/opposite relationships का analysis
    • किसी खास niche में सबसे expert users का analysis
  • पूरा data और code GitHub पर देखा जा सकता है

2 टिप्पणियां

 
GN⁺ 2024-05-10
Hacker News की राय
  • एक व्यक्ति के प्रोजेक्ट के हिसाब से यह खास तौर पर प्रभावशाली काम है
    समय के साथ sentiment analysis graph बहुत ध्यान खींचने वाला था, और Rust के बारे में इसे इस तरह पहली बार देखा, इसलिए दिलचस्प लगा। यह जानने की जिज्ञासा है कि समय बीतने पर सबसे सकारात्मक विषय कौन से थे, और क्या कोई ऐसा विषय था जो अचानक बहुत गिर गया
    “लगता है कि HN में कुल मिलाकर नकारात्मक sentiment काफ़ी है” यह वाक्य social media के बारे में अनुभव के हिसाब से सही लगता है। अलग-अलग social media platforms और समयावधियों के अनुसार sentiment की तुलना भी देखना मज़ेदार होगा

    • sentiment वाले हिस्से को मैं और गहराई से देखना चाहूँगा। जैसा आपने कहा, किसी खास query के बजाय समग्र overview देखना भी दिलचस्प होगा
      नकारात्मक sentiment इसलिए ज़्यादा नज़र आया क्योंकि मैं मूल रूप से एक ज़्यादा स्पष्ट sentiment graph की उम्मीद कर रहा था। आम तौर पर neutral~positive रहना चाहिए, और positive posts के आसपास positive तथा negative posts के आसपास negative की तरफ़ उछाल दिखना चाहिए—मैंने ऐसा सोचा था, लेकिन लगभग हर query में sentiment लगभग हमेशा नकारात्मक था। positive posts भी, मॉडल और approach के हिसाब से, काफ़ी नकारात्मकता खींचते दिखे। दोनों ही ग़लत हो सकते हैं, इसलिए बाद की ब्लॉग पोस्ट में इसे और गहराई से देखना चाहूँगा
    • social media platforms और समय के अनुसार sentiment के साथ-साथ दिन के समय और weekday/weekend भी साथ में देखना अच्छा रहेगा
    • कुछ महीने पहले मैंने AI, blockchain, remote work, और Rust पर HN comments sentiment का विश्लेषण करते हुए एक ब्लॉग पोस्ट लिखी थी। उस लेख के बिलकुल आख़िर का अंतिम graph इसी विषय से जुड़ा है
      https://openpipe.ai/blog/hn-ai-crypto
    • यह सच में अफ़सोस की बात है कि HN API comments के vote count उपलब्ध नहीं कराता। अगर upvote/downvote के आधार पर weight दिया जाए, तो sentiment analysis कैसे बदलता है यह जानना दिलचस्प होगा
      इसका कोई ठोस आधार नहीं है, लेकिन लगता है कि engineers आम तौर पर आलोचनात्मक होते हैं, और positive feedback बार-बार लिखने के बजाय +1 दबाने की तरफ़ झुकते होंगे। आलोचना वे ज़्यादा सीधे लिखते हैं :)
    • Crypto भी शायद उसी श्रेणी में आएगा
  • यह data engineering/MLOps से परिचित न होने वाले लोगों के लिए एक अच्छा उदाहरण है
    points पर HDBSCAN से hierarchical clusters बनाकर, मॉडल से अंदरूनी cluster names generate कराने का तरीका प्रस्तावित है। फिर मौजूदा node से connectivity के आधार पर details दिखाते हुए leaf तक topics को explore करना आसान हो जाएगा
    group colors और स्पष्ट होने चाहिए, और clusters हों तो मदद मिलेगी। अलग-अलग posts के text size को पूरे dataset या मौजूदा search के हिसाब से importance/relevance के अनुसार बदलना चाहिए। अगर अंदरूनी cluster summaries ज़्यादा हों, तो zoom in करने से पहले कई posts को group summaries से बदला जा सकता है, जिससे text clutter कम होगा

    • जिन लोगों के पास GPU है, उनके लिए यह ध्यान देने योग्य है कि HDBSCAN cuML में बहुत optimized है
      https://docs.rapids.ai/api/cuml/stable/api/#clustering / https://developer.nvidia.com/blog/faster-hdbscan-soft-cluste...
    • अच्छे pointer के लिए धन्यवाद। अफ़सोस है कि hierarchical clustering को देखने का समय नहीं मिला, लेकिन यह मेरी to-do list में है
      map को और स्पष्ट बनाने वाली बात भी अच्छी लगी, और मुझे लगता है कि सुधार के लिए काफ़ी आसान approaches हैं। इसे भी to-do list में जोड़ लिया है :)
  • प्रोजेक्ट का दायरा हैरान कर देने जितना बड़ा है
    लेकिन jina है या bge-3/flag, embeddings और tokenizer तकनीकी विषयों के लिए शायद ठीक से फिट नहीं बैठते। सामान्य भाषा के शब्दों के लिए ठीक है, लेकिन “xaml”, “simd” जैसे तकनीकी concepts खोजने पर, input को tokenize करने के बाद ध्वनि में मिलते-जुलते शब्द पकड़ने की तरफ़ झुकाव दिखता है
    रचनात्मक फ़ीडबैक के तौर पर, अगर विषय बहुत niche हो और नतीजे न हों, तो वही “HN leaderboard” results बार-बार न दिखाने का कोई तरीका अच्छा होगा। जब embedding किसी अनजान शब्द को search करता है, तो “Stephen Hawking has died” अक्सर सामने आ जाता है
    sentiment analysis भी कितना सही काम कर रहा है, इस पर भरोसा नहीं बनता। वास्तविकता से मेल न खाते हुए नकारात्मक sentiment बहुत ज़्यादा दिखा, और “Mr Rogers” जैसी चीज़ खोजने पर भी, जिसे HN बहुत सकारात्मक नज़रिए से देखेगा, एक तीखा नकारात्मक peak आता है। “Carter” खोजने पर Rosalynn Carter के निधन से जुड़ा एक बहुत बड़ा नकारात्मक peak आता है, जबकि असली पोस्ट Carter दंपति के शानदार कामों के बारे में थी
    “समय के साथ लोकप्रियता” को उस महीने/साल की posts के median vote count से normalize करना चाहिए। अगर सिर्फ़ post count plot करें, तो trend line लगातार ऊपर जाती रहती है। “diesel” की लोकप्रियता देखें तो समझ आएगा—यह शब्द 10 साल पहले peak पर था। या फिर post score की जगह keyword occurrence rate, या query के साथ cosine similarity index x से कम होने वाले items की संख्या जैसी कोई विधि होनी चाहिए
    posts पर क्लिक करके उन्हें हटाने और similarity threshold को फिर से calculate करने वाला dynamic feature शानदार है

    • यह programmatically कैसे पता लगाया जा सकता है कि कोई embedding model किसी खास term या word को पहचान नहीं पा रहा?
  • लगभग यही काम किसी भी dataset पर करने वाला एक शानदार tool है: https://github.com/enjalot/latent-scope
    बेशक, मूल प्रोजेक्ट के scale की वजह से उसमें काफ़ी दिलचस्प complexity जुड़ जाती है, और यह tool इतने बड़े scale को संभाल नहीं सकता, लेकिन medium-sized datasets के लिए अच्छा है

  • मैं यह विश्लेषण करना चाहता हूँ कि क्या HN पर self-promotion बढ़ा है।
    यहाँ self-promotion को “Show HN: Something ...” नहीं, बल्कि “Show HN: I ...” फ़ॉर्मेट की पोस्ट के रूप में परिभाषित किया गया है।
    अभी top 100 में, उदाहरण के लिए, “Show HN: Exploring HN by mapping and analyzing 40M posts and comments for fun”, “Show HN: Browser-based knitting (pattern) software” self-promotion शीर्षक नहीं हैं। दोनों में subject क्रमशः exploration और software हैं।
    इसके विपरीत, “Show HN: I built a non-linear UI for ChatGPT”, “Show HN: I created 3,800+ Open Source React Icons” self-promotion शीर्षक हैं। दोनों में subject “I” है।
    Algolia search results में 1 अप्रैल से शुरू होने वाले हर साल के लिए “Show HN: I” से शुरू होने वाले शीर्षकों को साधारण रूप से जाँचकर, उस साल के कुल result count से भाग देकर ग्राफ बनाया जाए, तो वह इस तरह था:
    2023 ****************************************
    2022 ***********************************
    2021 ***************************
    2020 **************************************
    2019 *************************
    2018 *************
    2017 *******
    2016 **********
    2015 ********
    2014 ************
    2013 *********************
    2012 *****************
    2011 *********
    2010 ***
    जब मैं बड़ा हो रहा था, तब आम तौर पर self-promotion को एक बुरा personality trait माना जाता था। मुझे सिखाया गया था कि आपके काम अपने-आप आपका प्रचार करें, न कि आप उस ओर ध्यान खींचें; लेकिन लगता है कि वह संस्कृति बदल रही है।
    अगर self-promotion सचमुच बढ़ा है, तो मैं सोचता हूँ कि क्या यह social media वगैरह का प्रभाव है। YouTube पर भी ऐसा ही बढ़ाव महसूस होता है, लेकिन वहाँ मेरे पास केवल यह अनुभव है कि बहुत-से recommended videos “I.....” से शुरू होते हैं, डेटा नहीं है।

    • self-promotion की परिभाषा मेरे सामान्य समझ से थोड़ी अलग है। आम तौर पर, अगर कोई व्यक्ति अपने बनाए हुए किसी चीज़ को प्रमोट करता है, तो मैं उसे self-promotion मानता हूँ। इसलिए जिन दो उदाहरणों को self-promotion नहीं कहा गया, वे भी मेरी परिभाषा में self-promotion हैं।
      यानी, आपने self-promotion और non-self-promotion में जो बँटवारा किया है, वह मेरे हिसाब से ऐसे मामलों का अंतर है जहाँ शीर्षक बहुत स्पष्ट रूप से self-promotion दिखाता है, बनाम जहाँ यह कम स्पष्ट है। फिर भी “Show HN” वाक्यांश खुद केवल self-promotion के लिए ही इस्तेमाल होता लगता है, इसलिए “I” न होने पर भी इस परंपरा को जानने वाला व्यक्ति समझ जाएगा कि यह self-promotion है।
    • हर Show HN लेखक द्वारा बनाई गई चीज़ ही होनी चाहिए, इसलिए जो बात implicit है उसे explicit कर देने से क्या चीज़ ज़्यादा self-promotional हो जाती है, यह मुझे स्पष्ट नहीं है।
      इन सबका अर्थ यही है: “देखो, मैंने एक बढ़िया चीज़ बनाई है, तुम्हें कैसी लगती है?”
    • यह बात Einstein की Walter Isaacson द्वारा लिखी गई जीवनी में भी काफ़ी आती है, इसलिए लोग इस प्रवृत्ति को बहुत पहले से देख रहे हैं।
      उदाहरण के लिए, जर्मनों ने Einstein पर self-promotion करने का आरोप लगाया था, जबकि दूसरी तरफ़ अमेरिका में celebrity culture था। यह एक चक्रीय घटना भी हो सकती है।
  • इस साल HN पर मैंने जो पोस्टें देखीं, उनमें यह निःसंदेह सबसे शानदार लगती है।

  • पहली नज़र में यह स्पष्ट नहीं था, लेकिन असली app यहाँ है: https://hn.wilsonl.in/

    • सोचता हूँ क्या landing page का link जानबूझकर लगभग अंत में रखा गया है। इस तरह केवल वही लोग साइट तक पहुँचते हैं जिन्होंने सच में पोस्ट पढ़ी हो।
      मैं तंज नहीं कर रहा, मुझे यह अच्छा विचार लगता है।
    • search links शायद shareable नहीं हैं, या उनमें search query शामिल नहीं होती दिखती।
      मैं यह भी जानना चाहता हूँ कि search phrase को क्या शब्द-दर-शब्द embed किया जाता है, और क्या इसमें वही model इस्तेमाल होता है जो documents के लिए किया गया। मैंने “lead generation” खोजा, जो एक ठीक multi-word embedding होने पर समझ में आना चाहिए, लेकिन lead poisoning से जुड़े results आ गए।
    • मैंने वहाँ खुद को और अपनी पोस्टों को ढूँढ लिया! बढ़िया।
  • UMAP के लिए एक आधुनिक recommendation Parametric UMAP है: https://umap-learn.readthedocs.io/en/latest/parametric_umap....
    यह एक छोटे Keras MLP को train करता है ताकि UMAP loss को minimize करते हुए 2D में dimensionality reduction किया जा सके। फ़ायदा यह है कि यह model छोटा होता है, इसलिए इसे save और reuse किया जा सकता है, और अनदेखे नए डेटा पर भी prediction किया जा सकता है। पारंपरिक रूप से train किया गया UMAP model बड़ा होता है। साथ ही, यह GPU का उपयोग करता है, इसलिए सिद्धांततः training काफ़ी तेज़ होनी चाहिए।
    कमी यह है कि Python UMAP package का implementation बहुत अच्छा नहीं है, और यह expanded full node/edge dataset को GPU पर बनाकर push करता है। इसलिए out-of-memory होने से पहले लगभग 100,000 embeddings तक ही training हो पाती है।
    UMAP → HDBSCAN → AI cluster labeling तक जाने वाली पूरी unsupervised pipeline इतनी उपयोगी है कि इससे अधिक scalable Parametric UMAP implementation बनाने का मन होता है।

    • एक तेज़ GPU implementation cuML में है। समझ नहीं आता कि cuML इतना कम जाना-पहचाना क्यों है।
    • ऊपर-ऊपर देखने पर लगता है कि implementation पूरा graph, यानी सभी edges, GPU पर push कर देता/देती है। training के दौरान edge sampling करने से इसे कम किया जा सकता है।
  • यह काम किसी exploratory hobby project जैसा दिखने के बावजूद हैरान करने वाली हद तक बड़ा है। उपलब्धि को कम करके नहीं आँक रहा; यह सच में शानदार है, लेकिन इसमें लगे प्रयास की मात्रा देखकर हैरानी हुई
    सिर्फ embedding गणना के लिए 150 GPU इस्तेमाल किए गए, और सर्वरों के बीच संचार के लिए db-rpc और queued नाम के दो custom system विकसित किए गए। इसके अलावा भी काफी सहायक काम और computation था
    इस प्रोजेक्ट का संदर्भ जानने की जिज्ञासा है। यह भी जानना चाहूँगा कि ऐसे शोध के लिए फंडिंग और समय कैसे मिला
    इसी तरह के काम को पेशेवर तौर पर काफी बार कर चुके व्यक्ति के नज़रिए से कहूँ तो, मैंने academic papers और patent landscape की mapping की है, लेकिन 150 GPU सच में ज़रूरी थे या नहीं, इस पर मुझे संदेह है। अगर अंत में करना 2D projection और clustering ही है, तो पारंपरिक bag-of-words या topic modeling कहीं ज़्यादा आसान और सस्ती होती, और गुणवत्ता में भी शायद ही कोई महसूस होने वाला फर्क आता। author और comment thread graph का इस्तेमाल करके भी मिलते-जुलते नतीजे मिल सकते हैं

    • लागत का ज़िक्र पोस्ट में नहीं कर पाया, लेकिन यह कुछ सौ डॉलर के स्तर पर था, इसलिए hobby project के रूप में भी काफी accessible था
      GPU उम्मीद से सस्ते थे, और ज्यादातर scaling मैंने सिर्फ इसलिए की क्योंकि मुझमें धैर्य कम था :) पूरा cluster भी सिर्फ कुछ घंटों के लिए चला
      अगर आपने जो काम किया है उसका कोई लिंक हो तो मैं देखना चाहूँगा। दिलचस्प लग रहा है, और पढ़ना चाहूँगा
    • लेखक निश्चित रूप से बहुत सक्षम है। यह भी दिलचस्प है कि वह HN पर पोस्ट तो करता है, लेकिन 2018 के बाद से कोई comment नहीं किया, और फिर उसने यह प्रोजेक्ट शुरू किया
      फंडिंग और समय की बात करें तो, संभव है कि वह अगली नौकरी या roles के बीच रहा हो और अपने पिछले करियर या business से आर्थिक रूप से सफल रहा हो, इसलिए इसे अपनी जेब से फंड किया हो। GPU utilization भी बहुत efficient था, इसलिए लागत शायद इतनी बड़ी नहीं रही होगी
    • सस्ते embedding का इस्तेमाल करके भी काफी अच्छे नतीजे मिल सकते हैं
      ऐसे embedding पर probability-calibrated SVM जैसी classical machine learning लगाकर classification और clustering में अच्छे परिणाम मिलते हैं, और speed, LLM fine-tuning की तुलना में 100 गुना से भी अधिक तेज होती है
  • आम तौर पर इसे इस demo की तरह नहीं किया जाता, बल्कि vectors को normalize किया जाता है
    normalized vectors का उपयोग करने पर Euclidean distance दो vectors के endpoints के बीच की दूरी मापता है। दूसरी ओर cosine distance यह मापता है कि एक vector दूसरे vector पर project होने पर उसकी लंबाई कितनी है

    • normalization की समस्या यह है कि इससे एक degree of freedom खो जाती है। visualization में यह लगभग एक dimension खो देने जैसा है
      normalized 2D vector वास्तव में सिर्फ 1D vector रह जाता है। अगर आप 2D संबंध दिखाना चाहते हैं, तो फिर 2 degree of freedom वापस पाने के लिए 3D vector का इस्तेमाल करना होगा
 
ggg213 2024-05-10

शीर्षक छूट गया है।