2 puan yazan GN⁺ 2024-05-10 | 2 yorum | WhatsApp'ta paylaş
  • Hacker News’in herkese açık API’sinden 40 milyondan fazla öğe toplayıp 30 milyondan fazla yorum ve 4 milyon gönderiye gömme, meta veri ve gövde metni ekleyen bir arama, harita ve analiz projesi
  • Yalnızca başlıkları gömen ilk yaklaşım, belirsiz başlıklar ve Ask HN/Show HN yanlılığı nedeniyle sınırlı kaldı; bağlantı verilen web sayfasının gövdesini, üst yorumları ve yorumların ata bağlamını birlikte kullanan bir yaklaşıma geçildi
  • İşleme ölçeği büyüdükçe RunPod’dan yaklaşık 150 GPU, Rust kuyruk servisi, HTTP/2 DB proxy’si, UMAP, Canvas rendering ve edge sunucuları birleştirildi; model değişiminden sonra giriş başına gömme süresi yaklaşık 600 ms’den 6 ms’ye düştü
  • Arama sıralaması basit dize eşleşmesi değil; anlamsal ilgiyi, sosyal sinyalleri ve güncelliği yansıtmak için kosinüs benzerliği, HN puanı ve zaman ağırlığını birlikte kullanıyor
  • Herkese açık demo yalnızca 10 Nisan 2024 civarına kadarki verileri içeriyor; tüm veri ve kod GitHub’da yayımlandı ve arama, öneri, kullanıcı analizi ve gerçek zamanlı güncelleme deneylerinde kullanılabilir

Proje kapsamı ve açık veri

  • Hacker News’teki tüm gönderileri anlamsal uzayda konumlandıran bir harita oluşturuldu; arama, analiz ve görselleştirme araçları da birlikte geliştirildi
  • Çıkış noktası metin gömme deneyleriydi; HN, çok sayıda seçilmiş içeriğe sahip olduğu ve tüm içerikleri programatik olarak sunduğu için uygun bir veri kümesi olarak seçildi
  • Gömmeler, metni yüksek boyutlu uzayda noktalar olarak temsil eder; mutlak konumdan çok noktalar arasındaki göreli mesafe faydalıdır
  • Beklenen kullanım alanları üç taneydi
    • HN’de birikmiş içerikte anlam temelli arama
    • İlgi alanlarına göre kişiselleştirilmiş öneriler
    • Topluluk içinde konulara göre duygu, popülerlik ve karşıt bakış açısı analizi
  • 30 milyondan fazla yorum ve 4 milyon gönderi veri kümesi sürümü olarak yayımlandı
    • ID, puan, yazar gibi meta verileri içerir
    • Gömmeleri içerir
    • Yorum metinlerini ve taranmış web sayfası metinlerini içerir
  • Kod hackerverse GitHub deposunda yayımlandı

Hacker News verilerini toplama

  • HN, basit bir herkese açık API sunar ve tüm nesneler item olarak sorgulanır
  • maxitem.json en büyük ID’yi verir; yazının yazıldığı sırada en büyük ID 40 milyonu aşıyordu
  • Ortalama yanıt süresi 10 ms olsa bile 40 milyon öğeyi sıralı taramak 4 günden fazla süreceğinden paralel işleme gerekiyordu
  • Node.js ile hızlı bir toplama servisi yapıldı, ancak semafor ve Promise kuyruğu yaklaşımında CPU zamanının çoğu kullanıcı alanındaki JS kodunda harcandığı için yavaştı
  • Daha sonra worker_threads API’siyle fetch işleri tüm CPU’lara dağıtıldı ve tüm çekirdekleri doyuracak şekilde performans iyileştirildi
  • Paralel toplamada sıra karıştığı için, kesinti durumunda eksik oluşmaması adına tamamlanma işaretçileri ID sırasıyla kaydedildi
  • HN API’de gözlemlenen bazı özellikler de vardı
    • Puan -1’in altına inmiyor gibi görünüyor
    • Gönderilerin downvote sayısı ve yorumların oy sayısı alınamıyor
    • Bazı gönderi ve yorumlarda silinmiş ya da flag’lenmiş durumda olmasalar bile başlık, metin ve URL boş
    • Yorum ID’si atasından küçük olabiliyor; bunun nedeni yorum ağacındaki taşınmalar olabilir
  • HN tarayıcısı ayrıca ayrı bir TypeScript projesi olan crawler-toolkit-hn olarak da ayrıldı

İlk gömme ve altyapı

  • Başta, yalnızca gönderi başlıklarının anlam temsilini yeterince sağlayacağı düşünülerek gömmeler oluşturuldu
  • Model karşılaştırması için Massive Text Embedding Benchmark referans alındı; ilk seçilen model BGE-M3 oldu
  • BGE-M3, genel yoğun gömmelerin yanı sıra lexical weights de üretebildiğinden BM25 benzeri yöntemlerle birleştirilen hibrit aramada kullanılabiliyor
  • Gömme üretim altyapısı basit değildi
    • İyi modeller yüz milyonlarca ila milyarlarca parametreye sahip olabilir
    • GPU’da çok daha verimlidirler, ancak GPU kümeleri pahalıdır
    • Çıkarım giriş başına yüzlerce ms sürerse tek GPU ile 40 milyon girdiyi işlemek neredeyse 1 yıl ölçeğine çıkar
    • Veri/sunucu ile GPU’lar ayrı yerlerde olduğundan GPU’ların boş kalmaması için pipeline’ın korunması gerekir
  • RunPod kullanılarak veri merkezlerinde çalışan GPU makineleri konteyner olarak dağıtıldı ve RTX 4090 gibi görece ucuz GPU’lardan yararlanıldı
  • GPU’lar dünyanın dört yanına dağılmış olduğundan DB bağlantı gecikmesi ve bağlantı overhead’i sorun olunca db-rpc geliştirildi
    • SQL sorgularını HTTP/2 üzerinden yerel DB’ye proxy’ler
    • Büyük bir paylaşımlı bağlantı havuzu kullanır
    • HTTP/2 multiplexing ile tek bağlantıda birden fazla sorguyu işler
  • AWS SQS, milyonlarca küçük iş mesajında düşük hız limitleri ve mesaj başına maliyet nedeniyle yük oluşturduğundan RocksDB tabanlı Rust kuyruk servisi queued geliştirildi
    • Tek bir node’da 100K+ op/s işler
    • Batching, mesaj boyutu, hız limiti ve maliyet yükünü azaltır
  • Yaklaşık 150 GPU’ya kadar ölçeklenince 40 milyon gönderi ve yorum birkaç saat içinde gömüldü
  • O dönemde giriş başına gömme maliyeti yaklaşık 600 ms idi ve GPU kullanımı tüm süre boyunca yüksek kaldı

Web sayfası taramayla bağlamı güçlendirme

  • Yalnızca başlıkları gömme yaklaşımı yeterli değildi
    • Birçok gönderinin tuhaf, yaratıcı veya belirsiz başlıkları var
    • Ask HN ve Show HN ifadeleri başlıkların tamamında büyük yer kapladığından, konudan bağımsız olarak birlikte kümelenme eğilimi gösteriyordu
  • Metin gönderileri ve yorumlar için kendi metinleri kullanılabiliyordu; ancak bağlantılı gönderilerin çoğunda bağlantı verilen web sayfasının taranması gerekiyordu
  • Rust servisiyle URL’ler alındı ve HTML’den başlık, görsel, yazar, gövde metni gibi meta veriler ayrıştırıldı
  • İlk Node.js sürümü CPU yoğun işlerde Rust sürümünden 10 kat yavaştı; Rust ile yeniden yazılarak performans iyileştirildi
  • Metin çıkarma, HTML’i scraper ile ayrıştırıp anlamsal olarak ana içerik olmayan HTML5 öğelerini kaldırdıktan sonra kalan ağacı dolaşma şeklindeydi
  • Link rot da önemliydi
    • Yaklaşık 200 bin URL; 404, DNS sorgu hatası veya bağlantı zaman aşımı nedeniyle başarısız oldu
    • Bu, 4 milyon sayfanın %5’inden azı demek
  • Eksikleri azaltmak için Internet Archive’ın Wayback API ile eski makalelerin bir kısmı getirildi
    • Internet Archive’ın hız limiti dakikada yaklaşık 5 istek düzeyinde, çok düşüktü

İkinci gömme stratejisi

  • Web sayfaları uzun olsa da BGE-M3, 8192 token’lık context window destekliyor
  • Ancak BGE-M3 yavaş olduğundan jina-embeddings-v2-small-en ile değiştirildi
    • Parametre sayısı çok daha az
    • MTEB’ye göre performansı da iyi
    • Çıkarım süresi yaklaşık 6 ms’ye düşerek 100 kat hızlandı
  • Uzun girdiler nedeniyle batch boyutu artırılınca OOM oluştuğundan GPU’lar tamamen doyurulamadı
  • Metni az olan veya getirilemeyen sayfaları tamamlamak için gönderinin üst HN yorumları gövde metninin arkasına eklendi
    • Üst seviye yorumlar için item.kids’in zaten sıralanmış olduğu varsayıldı
    • Silinmiş, dead veya negatif puanlı yorumlar hariç tutuldu
    • Girdi en fazla 64 KiB ile sınırlandı
  • Yorumlar tek başına anlam bakımından yetersiz olabildiği için ata yorumlara ve gönderi başlığına kadar geri gidilerek daha uzun bir bağlam oluşturuldu
  • Gömme ve metin gibi büyük değerler ayrı bir kv tablosunda saklandı
    • Satır içinde birlikte saklanırsa satır şişer
    • Küçük sütun güncellemeleri de pahalı hale gelir
    • Şema değişiklikleri de pahalılaşır

UMAP ile 2D anlamsal harita oluşturma

  • UMAP, yüksek boyutlu gömmeleri daha düşük boyutlara indirirken anlamsal ilişkileri korumayı amaçlayan bir boyut indirgeme tekniğidir
  • 1024 boyutlu gömme vektörleri 2D noktalara indirgenerek saçılım grafikleri ve harita görselleştirmelerinde kullanıldı
  • UMAP, PyNNDescent grafiğini ve özgün gömmeleri girdi olarak aldı; metric="cosine", n_components=2 kullanıldı
  • Milyonlarca yüksek boyutlu girdiyi eğitmek uzun sürdüğü için EC2’de c7i.metal-48xl VM’i kullanıldı
    • 96 çekirdekli işlemciden azami ölçüde yararlanıldı
    • Yaklaşık 1 saat 30 dakika sonra 2D matris oluşturuldu
  • Oluşturulan 2D gömmeler ve eğitilmiş UMAP modeli kaydedilerek, daha sonra yeni gömmelerin de yeniden eğitim olmadan dönüştürülebilmesi sağlandı
  • İlk saçılım grafiğinde nokta sayısı çok fazlaydı; yoğunluğu azaltmak ve başlıkları göstermek için her ızgara hücresinde yalnızca en yüksek puanlı gönderi seçildi
  • Daha fazla bağlam içeren ikinci gömmede, yalnızca başlıkla konumlandırılması zor olan gönderiler ilgili içeriklerin yakınına daha doğru biçimde yerleştirildi

Kosinüs benzerliği ve arama sıralaması

  • Gömmelerden yararlanmanın temelinde iki gömme arasındaki benzerliği bulmak vardır
  • Metin gömmelerinde, genel Öklid mesafesinden çok kosinüs mesafesi/benzerliği daha sık kullanılır
  • Kosinüs mesafesi, büyüklükten çok yönün önemli olduğu durumlarda yararlıdır
    • X ile ilgili uzun bir tartışma, Y ile ilgili uzun bir tartışmadan çok X’e benzemelidir
    • Büyüklüğü hesaba katmak bu ilişkiyi yanıltıcı gösterebilir
  • Kullanılan temel hesaplama, gömme matrisi ile sorgu gömmesinin dot product’ıdır
  • Vektörler birim vektörse ayrıca büyüklüğe bölme gerekmez
  • Arama sonuçları yalnızca saf benzerliğe göre sıralanmaz
    • Kosinüs benzerliği büyük bir faktördür, ancak tek faktör değildir
    • HN puanı sosyal kanıt olarak kullanılır
    • Zaman ağırlığı, güncelliğin önemli olduğu sorgularda eski içeriklerin hızla geriye düşmesi için log(age) ile orantılı negatif bir unsur olarak yansıtılır

Tarayıcı harita uygulaması

  • Amaç, HN gömme uzayını Google Maps gibi gezilebilen interaktif bir haritaya dönüştürmekti
  • İstenen davranışlar netti
    • Pinch hareketi veya fare tekerleğiyle yakınlaştırınca daha fazla nokta gösterilir
    • Noktalar arasındaki mesafe de büyür
    • Bazı noktalarda etiket olur, hepsinde olmaz
    • Bir noktaya tıklanınca gönderi ayrıntıları gösterilir
    • Mobil ve masaüstünde hem dokunma hem fare desteklenir
  • Milyonlarca nokta olduğu için tüm noktaları bir kerede istemciye göndermek uygun değildi
  • Harita uzayını ızgara karolara bölüp, istemcinin yalnızca ihtiyaç duyduğu karoları aldığı bir yapı kullanıldı
    • Karolar (x, y) koordinatlarıyla tanımlanabilir
    • S3 gibi KV depolarında saklanabilir
    • Sunucu tarafı mantığı olmadan dağıtımı kolaydır
  • Yakınlaştırma seviyeleri LOD yaklaşımıyla ele alındı
    • Her seviyede eksen başına 2 kat daha fazla ızgara hücresine bölünür
    • Önceki seviyede seçilen noktalar sonraki seviyeye de kopyalanarak yakınlaştırırken noktaların kaybolmaması sağlanır
  • Karo boyutu, sıkıştırıldığında 20KiB’nin altında hedeflendi
    • Yaklaşık 1.500 noktayla sınırlandırıldı
    • Nokta başına (x, y) için 8 bayt, ID için 4 bayt, puan için 2 bayt kullanıldı
  • Web uygulaması render işleminde binlerce DOM öğesi kullanma yaklaşımı performansı ciddi biçimde bozdu
  • Nihai uygulama Canvas kullandı ve viewport her güncellendiğinde yeniden çizim yapan bir yaklaşımla çalıştı
    • Her karede binlerce nokta yeniden çizilse bile akıcı ve basit çalışır
  • Etiketleme, en yüksek puanlı gönderileri yinelemeli olarak seçip mevcut etiketlerle çakışanları dışarıda bırakma şeklinde yapıldı
    • Çakışma denetimi için RBush R-tree uygulaması kullanıldı
    • Etiket uzunluğu, tarayıcı measureText() yerine başlık uzunluğu bayt dizisi ve ayarlanmış bir formülle yaklaşık hesaplandı
  • İlk etiket kutuları ve çakışma hesapları CPU yoğun olduğu için Web Workers’a taşındı
  • OffscreenCanvas da denendi, ancak render mantığı zaten verimli olduğu için büyük bir etkisi olmadı

Arazi, sınırlar ve şehir etiketleri

  • Haritada yalnızca noktalar olunca yön hissi ve görsel ilgi yetersiz kaldığı için arazi ve şehir kavramları eklendi
  • Gerçek coğrafya veya siyasi sınırlar olmadığından, arazi nokta yoğunluğunu temsil eden bir benzetme olarak kullanıldı
  • Nokta yoğunluğu; etkinliğin, ilginin, içeriğin, katılımın, popülerliğin ve tartışmanın fazla olduğu alanları hızla gösteren bir sinyal olarak kullanıldı
  • Başta Kernel Density Estimation düşünüldü, ancak standart kütüphane denemeleri çok uzun sürdü
  • Bunun yerine her nokta büyük bir ızgara hücresine eşlendi, hücre bazında sayımlar çıkarıldı ve ardından Gaussian blur uygulandı
  • Doğrusal yoğunluk değerlerinde çoğu alan 0’a yakın göründüğü için harita iyi görünmedi
  • log(density + 1) uygulanınca çok daha doğal bir katmanlaşma oluştu; farklı yoğunluk seviyelerinin buluştuğu yerler örtük sınırlar gibi görünmeye başladı
  • Devasa bir görsel yerine SVG yolları oluşturularak istemcide çokgenler olarak çizilmesi sağlandı
    • Yalnızca 4 renk olduğu için verimlidir
    • Yakınlaştırıldığında da sınırlar keskin kalır
    • OpenCV’nin contour fonksiyonuyla seviye bazında kapalı eğriler hesaplandı
  • Şehir etiketleri, belirli bir yarıçap içindeki ortak temayı temsil eder
  • Şehir adları gömülüp, kaydedilmiş UMAP modeliyle (x, y) konumları elde edildi
  • Otomatik üretim de denendi
    • LLM ile şehir adları oluşturulmak istendi, ancak istenen çıktıyı prompt ile istikrarlı biçimde almak zordu
    • K-means, insanların gruplayacağı türden anlamlı kümeleri çok fazla bulamadı
  • Sonuçta harita doğrudan gezilerek birkaç şehir elle yazıldı ve bu yaklaşık 1 saat sürdü

Edge dağıtımı ve yanıt verebilirlik

  • Harita gezintisinin hızlı ve tepkisel olması gerektiğinden, veri fetch gecikmesini azaltmak önemliydi
  • Başta tüm harita verileri Cloudflare R2’nin ENAM bölgesine konmuştu, ancak gecikme 600 ms’den birkaç saniyeye kadar çıkıyordu
  • Fiziksel gecikme yaklaşık 200 ms olsa bile, 100 ms’nin anında tepki gibi hissedilen eşik olduğu düşünüldüğünde bu yeterince iyi değildi
  • Gecikmeyi azaltmak için veriler kullanıcılara daha yakın noktalara taşındı
  • Virginia, San Jose, London ve Sydney’de küçük sunucular kuruldu ve veriler Rust sunucusuyla sağlandı
  • İstemci, birden fazla edge’in /healthz uç noktasını birkaç kez çağırır ve ilk yanıt veren sunucuyu seçer
  • Anycast veya CDN gibi yöntemler de mümkündü, ancak maliyet ve aşırı karmaşıklık nedeniyle kullanılmadı
  • Edge sunucu süreçlerinin bellek kullanımı, ham veriden 2–4 kat daha büyüktü ve bu soru işaretleri bıraktı
    • Yanlış tür kullanımı olasılığı
    • struct padding
    • Vec, HashMap fazla ayırma
    • Bellek ayırıcısında parçalanma veya verimsizlik olasılığı

Anlamsal arama sonuçları ve sınırlamalar

  • “entering the tech industry” gibi basit bir sorguda, çok upvote almış sonuçlar ile daha az dikkat çekmiş sonuçlar birlikte göründü; alaka ve yararlılık iyi görünüyordu
  • HN’nin mevcut arama hizmetleriyle karşılaştırıldığında, anlamsal gömme araması birebir metin eşleşmesi olmasa da sonuç bulabiliyor
  • “what happened to wework” gibi soru biçimli sorgular da WeWork’teki işten çıkarmalar, hisse fiyatı düşüşü, iflas gibi farklı yıllara yayılan sonuçları gösteriyor
  • Arama sonuçları gerçekten “what happened” sözcüklerini içermese veya soru biçiminde olmasa da eşleşiyor
  • Bir sorun, yeterince benzer olmayan sonuçların filtrelenmemesi nedeniyle tamamen alakasız alt sıralardaki sonuçların dahil olmasıydı
    • Bu, düzeltilmesi kolay bir sorun olarak ele alındı
  • “career growth” aramasında, kelimeleri birebir içermeyen yaratıcı ve çeşitli denemeler ortaya çıktı
  • HN’nin seçicilik kalitesi ve puanları arama kalitesine yardımcı oluyor
  • Uygulamada “linus rants”, “self bootstrapping”, “cool things with css” gibi sorgu önerileri hardcode edilmiş durumda

Sanal topluluklar ve yorum analizi

  • Gömme kullanarak sanal alt topluluk işlevi oluşturulabilir
  • Kullanıcı bir topluluk adı veya açıklaması girdiğinde, belirli bir benzerlik eşiğini aşan gönderiler anında gruplanır
  • HN’de gönderileri daha da ayrıntılı alt bölümlere ayıran bir özellik olmadığından, bu belirli ilgi alanları etrafında anında kürasyon oluşturma yöntemidir
  • Sonuç kartlarındaki snippet’ler ve görseller, web crawler’ın kaydettiği sayfa meta verilerinden alınır
  • Site ikonları, karmaşık meta veri ayrıştırması yerine istemcide alan adının /favicon.ico dosyasını alma yöntemiyle basitleştirildi
  • Yorum thread’leri de aynı şekilde gösterilebilir
  • Yorum puanı HN API tarafından sağlanmadığı için yalnızca kronolojik sıralama yapılabilir
  • Yorum puanı olmadan sıralama yapmak için kullanıcı yorum geçmişi, ilgili yorumun çevresindeki etkileşim, gönderi, konu ve içerik gibi unsurlardan yararlanılabileceği düşünülüyor
  • Belirli bir konuda etkili ya da aktif kullanıcıları bulmak da mümkün
    • “cloudflare” sorgusunda jgrahamc ve eastdakota üst sıralarda görünüyor
    • Bu iki kullanıcı sırasıyla Cloudflare’in CTO’su ve CEO’su
  • Bu işlem, yorumları ayrı ayrı sınıflandırmadan veya anahtar kelime araması kullanmadan, matris işlemleriyle yapılıyor
  • Ön filtrelemeden ziyade sonradan filtreleme genellikle daha hızlı ve yeterlidir
    • Ön filtreleme, gömme matrisinden karşılık gelen satırların çıkarılmasını gerektirdiği için devasa bellek kopyaları veya yavaş kısmi vektörleştirme hesaplamaları gerektirebilir
    • Önce benzer satırları bulup sonra sonuçları filtrelemenin daha iyi olduğu düşünülüyor
  • Minimum eşik önemlidir
    • İlgisiz öğeler bile 0,6 düzeyinde benzerliğe sahip olabilir
    • Eşik yoksa, çok fazla yorumu olan kullanıcılar sırf ölçek nedeniyle sıralamaya hâkim olabilir

Tüm yorum verisinde duygu ve popülerlik analizi

  • 30 milyon yorumla yapılmak istenen büyük ölçekli analiz popülerlik ve duygu üzerineydi
  • Amaç, HN’nin belirli bir konu hakkında zaman içinde nasıl hissettiğini, önemli olayların duygu üzerinde nasıl etki yarattığını ve ilgi alanlarının nasıl büyüyüp küçüldüğünü görmekti
  • Duygu verisi olmadığı için Hugging Face’in açık kaynaklı duygu sınıflandırma modeli kullanıldı
  • Seçilen model, sosyal medya içeriğiyle eğitilmiş TweetEval modeliydi
  • TweetEval kısa tweet’ler için bir model olduğundan, gömme sırasında olduğu gibi üst bağlam eklenmedi; girdi olarak yalnızca yorumun kendisi kullanıldı
  • Yorumlar kuyruğa alındı, işler GPU kümesinde işlendi ve sonuçlar kaydedildi
  • Model küçük olduğu için GPU verimliliğini artırmak üzere batch boyutu yükseltildi
  • Batch boyutunu artırmak daha fazla VRAM kullanır, ancak host-GPU bellek aktarımını azaltıp paralelliği artırabilir
  • Transformer modellerinde batch girdisinin dikdörtgen olması gerektiğinden, en uzun girdi uzunluğuna göre padding uygulanır
    • Birkaç kısa girdinin arasına tek bir uzun girdi karışırsa toplam girdi boyutu ve iç durum ciddi biçimde büyüyebilir
    • Bu nedenle bellek sıçramaları ve OOM oluşabilir
  • Rust duygu analizi örneğinde, Rust’a yönelik olumlu duygu genel olarak daha fazlaydı
    • Rust 1.0 duyurusu civarında olumlu bir sıçrama vardı
    • Daha olumsuz gönderiler, model ölçütlerine göre çok sayıda olumsuz yorumla ilişkiliydi
  • Dillere göre popülerlik de puan ve benzerlik ağırlıklandırılarak tahmin edildi
    • HN yorum puanı sağlamadığı için yorum puanları kullanılamıyor
    • Rust iyi gidiyor olsa da diğer diller kadar popüler görünmüyordu
    • Benzerlik eşiğinin ayarlanması gerekebileceğinden sonuçlar hatalı olabilir

GPU ile büyük ölçekli sayısal hesaplamayı hızlandırma

  • Analiz sorguları 32 çekirdekli bir makinede bile 10–30 saniye sürdüğü için etkileşimli deneyler açısından yavaştı
  • İndeks veya ön işleme üzerine düşünürken, vektörleştirilmiş sayısal hesaplamada GPU kullanma yaklaşımına geçildi
  • CuPy ve cuDF sırasıyla NumPy ve pandas’a benzer API’ler sunarken GPU üzerinde çalışır
  • Port etmek görece kolaydı ve sorgu süresi birkaç yüz ms seviyesine düştü
  • Hız yeterince yüksek olduğu için ANN grafiği de kullanılmadı
  • Zor kısım, büyük gömme matrisini GPU’ya yüklemekti
    • Yorum gömme matrisi 30M x 512 boyutundaydı
    • Sistem belleğine veya video belleğine matrisin 1 kopyasından fazlasını sığdırmak zordu
  • Basit bir yükleme yöntemi birden fazla kopya oluşturabilir
    • Diskten baytlar okunur
    • NumPy dizisi olarak yüklenir
    • CuPy dizisine dönüştürülür
    • GPU’ya kopyalanır
    • Bu süreç toplam 4 kopya oluşturabilir ve bunların 3’ü bellekte bulunur
  • Nihai yöntem, diskteki matrisi bellek eşlemeli hale getirmek, GPU’da aynı boyutta ilklendirilmemiş bir matrisi önceden ayırmak ve ardından parça parça kopyalamaktı
  • Bu yöntem, veriyi önce Python belleğine okumaktan kaçınır ve sistem RAM’i ile VRAM’i her biri için tam olarak 1 kopya kullanır

Demo ve sonraki adımlar

  • Demo uygulaması hn.wilsonl.in adresinde sunuluyor
  • Ana sayfa harita ve aramadan oluşur; sağ üstteki düğmelerle topluluk ve analiz araçlarına erişilebilir
  • Topluluk veya analiz sonucu URL’leri sorguyu URL’de sakladığından başkalarıyla paylaşılabilir
  • Demo veri kümesi 10 Nisan 2024 civarında sona eriyor; en yeni canlı gönderi ve yorumları içermiyor
  • İleride keşfedilmek istenen birkaç fikir var
    • Sürekli güncel tutulan canlı veri
    • HN’nin seçilmiş web’i üzerinde çalışan derin öğrenme tabanlı öneri sistemi
    • Yeniden sıralayıcı eğiterek arama sonuçlarını iyileştirme
    • Harita üzerindeki ilginç rotalar ve yolculuklar
    • Kullanıcılar arası benzerlik ve karşıtlık ilişkisi analizi
    • Belirli bir nişte en uzman kullanıcıların analizi
  • Tüm veri ve kod GitHub’da bulunabilir

2 yorum

 
GN⁺ 2024-05-10
Hacker News yorumları
  • Tek kişilik bir proje için özellikle etkileyici bir çalışma
    Zaman içindeki duygu analizi grafiği dikkatimi çekti; Rust’ı bu şekilde görmek de benim için ilk olduğundan ilginçti. Zamanla en olumlu algılanan konuların neler olduğunu, birden sert düşüş yaşayan bir konu olup olmadığını da merak ediyorum.
    “HN genelinde çok fazla olumsuz duygu var gibi” cümlesi de sosyal medya hakkında sezgisel olarak doğru geliyor. Sosyal medya platformlarına ve dönemlere göre duygu karşılaştırması görmek de eğlenceli olabilir.

    • Duygu tarafını daha derinlemesine kurcalamak istiyorum. Dediğin gibi belirli bir sorgu yerine genel görünüme bakmak da ilginç olabilir.
      Olumsuz duygunun göze çarpmasının nedeni, aslında daha belirgin bir duygu grafiği beklememdi. Genel olarak nötr~olumlu olacağını, olumlu yazıların çevresinde olumluya, olumsuz yazıların çevresinde olumsuza sıçrayacağını tahmin etmiştim; ama neredeyse tüm sorgularda duygu neredeyse her zaman olumsuzdu. Olumlu yazılar bile model ve yaklaşım açısından bakıldığında epey olumsuzluk çekmiş gibi görünüyordu; ikisi de yanlış olabilir, bu yüzden sonraki blog yazısında daha fazla incelemek istiyorum.
    • Sosyal medya platformu ve dönemlere göre duygunun yanı sıra saat dilimi ile hafta içi/hafta sonuna da birlikte bakılsa iyi olurdu.
    • Birkaç ay önce yapay zeka, blockchain, uzaktan çalışma ve Rust hakkındaki HN yorum duygusunu analiz eden bir blog yazısı yazmıştım. Yazının en sonundaki nihai grafik bu konuyla ilgili.
      https://openpipe.ai/blog/hn-ai-crypto
    • HN API’sinin yorumların oy sayılarını sağlamaması gerçekten üzücü. Artı/eksi oylarla ağırlık verilse duygu analizinin nasıl değişeceğini merak ediyorum.
      Dayanağım yok ama mühendisler genel olarak eleştirel olur; olumlu geri bildirimi tekrar tekrar yazmaktansa +1’e basmayı tercih ederler gibi geliyor. Eleştiriyi ise daha doğrudan yazarlar :)
    • Crypto da o kategoriye girer gibi.
  • Veri mühendisliği/MLOps’a aşina olmayan biri için iyi bir örnek
    Noktalar üzerinde HDBSCAN ile hiyerarşik kümeler oluşturup, modelle iç kümelere ad üretme yöntemini öneririm. Böylece mevcut düğümle bağlantısına göre alt başlıkları öne çıkararak yapraklara kadar konuları keşfetmek kolaylaşır.
    Grup renkleri daha belirgin olmalı; kümeler olursa yardımcı olur. Tekil yazıların metin boyutu, genel önemine ya da mevcut arama ölçütüne göre önem/alakalılık derecesine bağlı olarak değişmeli. Daha fazla iç küme özeti olursa, yakınlaştırana kadar birden çok yazı grup özetleriyle değiştirilebilir ve metin kalabalığı azalır.

  • Projenin kapsamı şaşırtıcı derecede büyük
    Ancak jina mı yoksa bge-3/flag mi bilmiyorum; embedding ve tokenizer teknik konulara pek iyi uymuyor gibi. Doğal dil sözcüklerinde sorun yok, ama “xaml”, “simd” gibi teknik kavramları aradığınızda girdiyi token’lara ayırdıktan sonra kulağa benzer gelen kelimeleri yakalamaya çalışma yönüne kayıyor.
    Yapıcı geri bildirim olarak, konu çok niş olduğu için sonuç yoksa aynı “HN sıralama tablosu” sonuçlarını tekrar tekrar göstermeyen bir yol olsa iyi olur. Embedding’in aşina olmadığı kelimeler arandığında “Stephen Hawking has died” sık sık çıkıyor.
    Duygu analizinin de ne kadar iyi çalıştığından emin değilim. Gerçeklikle pek örtüşmeyecek kadar fazla olumsuz duygu var gibi görünüyordu; HN’in ezici biçimde olumlu bakacağı “Mr Rogers” gibi şeyleri arayınca bile ciddi bir olumsuz pik çıkıyor. “Carter” arandığında Rosalynn Carter’ın vefatıyla ilgili dev bir olumsuz pik var; oysa asıl yazı Carter çiftinin yaptığı harika işlerden bahseden bir gönderiydi.
    “Zaman içindeki popülerlik” ilgili ay/yıldaki yazıların medyan oy sayısına göre düzeltilmeli gibi. Sadece yazı sayısını çizerseniz trend çizgisi sürekli yükselir. “diesel”in popülerliğine bakarsanız ne demek istediğimi görürsünüz; bu terim 10 yıl önce zirve yapmıştı. Ya da yazı puanı yerine anahtar kelime geçiş oranı ya da sorguyla kosinüs benzerliği indeksi x’ten küçük olan öğe sayısı gibi bir yöntem kullanılmalı belki.
    Yazılara tıklayıp kaldırarak benzerlik eşiğini yeniden hesaplayan dinamik özellik harika.

    • Belirli bir embedding modelinin belirli terimleri veya kelimeleri tanımadığını programatik olarak nasıl ayırt edebiliriz?
  • Neredeyse aynı işi herhangi bir veri kümesi için yapan harika bir araç var: https://github.com/enjalot/latent-scope
    Elbette asıl projenin ölçeği nedeniyle birçok ilginç karmaşıklık ekleniyor ve bu araç o ölçekte çalışamaz; ama orta büyüklükte veri kümeleri için iyi.

  • HN’de öz tanıtımın artıp artmadığını analiz etmek istiyorum
    Burada öz tanıtımı “Show HN: Something ...” değil, “Show HN: I ...” biçimindeki yazılar olarak tanımlıyorum
    Şu an ilk 100 içinde örneğin “Show HN: Exploring HN by mapping and analyzing 40M posts and comments for fun”, “Show HN: Browser-based knitting (pattern) software” öz tanıtım başlıkları değil. Bunlarda özne sırasıyla keşfetme ve yazılım
    Buna karşılık “Show HN: I built a non-linear UI for ChatGPT”, “Show HN: I created 3,800+ Open Source React Icons” öz tanıtım başlıkları. Her birinin öznesi “I”
    Algolia arama sonuçlarında, 1 Nisan’dan başlayan her yıl için “Show HN: I” ile başlayan başlıkları basitçe kontrol edip, bunu o yılın toplam sonuç sayısına bölerek grafiğe dökünce sonuç şöyleydi
    2023 ****************************************
    2022 ***********************************
    2021 ***************************
    2020 **************************************
    2019 *************************
    2018 *************
    2017 *******
    2016 **********
    2015 ********
    2014 ************
    2013 *********************
    2012 *****************
    2011 *********
    2010 ***
    Ben büyürken öz tanıtımın genel olarak kötü bir karakter özelliği sayıldığını düşünüyorum. Bana, kişinin davranışlarının onu tanıtması gerektiği, buna dikkat çekmemesi gerektiği öğretilmişti; ama bu kültür değişiyor gibi geliyor
    Öz tanıtım gerçekten arttıysa bunun sosyal medya vb. etkilerden kaynaklanıp kaynaklanmadığını merak ediyorum. YouTube’da da benzer bir artış hissediyorum; ancak “I.....” ile başlayan çok sayıda önerilen video gördüğüme dair yalnızca bir izlenimim var, veri yok

    • Öz tanıtım tanımın benim genelde düşündüğümden biraz farklı. Normalde bir kişi kendi yaptığı bir şeyi tanıtıyorsa bunu öz tanıtım olarak görürüm. Bu yüzden öz tanıtım olmadığını söylediğin iki örnek de benim tanımıma göre öz tanıtım
      Yani senin öz tanıtım ve öz tanıtım olmayan diye ayırdığın şey, benim ölçütüme göre başlığın bunun öz tanıtım olduğunu çok açık biçimde belli ettiği durumlarla daha az açık biçimde belli ettiği durumlar. Yine de “Show HN” ifadesinin kendisi zaten yalnızca öz tanıtım için kullanılıyor gibi, dolayısıyla “I” olmasa da geleneği bilen biri bunun öz tanıtım olduğunu anlayabilir
    • Tüm Show HN gönderilerinin yazarın yaptığı şeyler olması gerektiğine göre, örtük olanı açıkça söylemenin bir şeyi nasıl daha öz tanıtımcı yaptığını pek anlamıyorum
      Hepsi “bak, harika bir şey yaptım, ne düşünüyorsun?” anlamına geliyor
    • Einstein’ın Walter Isaacson biyografisinde de çokça ele alınan bir konu olduğu için insanlar bu eğilimi uzun zamandır gözlemliyor
      Örneğin Almanların Einstein’ı öz tanıtım yapmakla suçlaması, buna karşılık Amerika’da ünlü kültürünün olması gibi. Döngüsel bir olgu da olabilir
  • Bu yıl HN’de gördüğüm yazılar arasında açık ara en havalısı gibi

  • İlk bakışta belli değildi ama asıl uygulama burada: https://hn.wilsonl.in/

    • Açılış sayfası bağlantısını bilerek neredeyse en sona koyup koymadığını merak ediyorum. Yapı fiilen, yalnızca yazıyı gerçekten okuyanların siteye gitmesini sağlıyor
      Alay etmiyorum; iyi bir fikir olduğunu düşünüyorum
    • Arama bağlantısı paylaşılabilir değil gibi ya da içinde arama terimi yer almıyor gibi görünüyor
      Arama ifadesini kelime kelime embedding’e dönüştürüp dönüştürmediğini, belgeler için kullandığınla aynı modeli kullanıp kullanmadığını da merak ediyorum. “lead generation” aradım; düzgün bir çok kelimeli embedding bunun anlaşılması gereken bir ifade olduğunu anlamalıyken kurşun zehirlenmesi sonuçları çıktı
    • Kendimi ve yazılarımı orada buldum! Güzel
  • UMAP için modern bir öneri olarak Parametric UMAP var: https://umap-learn.readthedocs.io/en/latest/parametric_umap....
    Küçük bir Keras MLP eğiterek UMAP kaybını en aza indirirken 2 boyuta boyut indirgeme yapıyor. Avantajı, bu modelin küçük olması; kaydedilip yeniden kullanılabiliyor ve bilinmeyen yeni veriler için de tahmin yapabiliyor. Geleneksel olarak eğitilmiş UMAP modeli büyük olur. Ayrıca GPU kullandığı için teoride eğitim çok daha hızlı
    Dezavantajı, Python UMAP paketindeki implementasyonun pek iyi olmaması ve genişletilmiş tüm düğüm/kenar veri kümesini GPU’da oluşturup oraya yüklemesi. Bu yüzden bellek yetersizliği oluşmadan önce yaklaşık 100 bin embedding’e kadar eğitilebiliyor
    UMAP → HDBSCAN → yapay zeka ile küme etiketleme şeklinde ilerleyen tamamen gözetimsiz pipeline o kadar kullanışlı ki, daha ölçeklenebilir bir Parametric UMAP implementasyonu yapmak istiyorum

    • Hızlı GPU implementasyonu cuML içinde var. cuML’in neden bu kadar az bilindiğini pek bilmiyorum
    • İlk bakışta bunun nedeni implementasyonun tüm grafiği, yani tüm kenarları GPU’ya yüklemesi gibi görünüyor. Eğitim sırasında kenar örneklemesi yapılırsa bu hafifletilebilir
  • Keşif amaçlı bir hobi projesi gibi görünen bir şey için şaşırtıcı derecede büyük bir çalışma. Başarıyı küçümsemek istemiyorum; gerçekten harika, ama harcanan emek beni şaşırttı
    Yalnızca embedding hesaplamaları için 150 GPU kullanmış; sunucular arası iletişim için de db-rpc ve queued adlı iki özel sistem geliştirmiş. Etraftaki işler ve hesaplamalar da oldukça fazlaymış
    Projenin bağlamını merak ediyorum. Böyle bir araştırma için gereken finansmanı ve zamanı nasıl bulduğunu da merak ediyorum
    Benzer işleri profesyonel olarak epey yapmış biri olarak, akademik makaleler ve patent alanlarını haritalamıştım; 150 GPU’nun gerçekten gerekli olup olmadığından pek emin değilim. Sonuçta 2 boyutlu projeksiyon ve kümeleme yapılacaksa, geleneksel bag-of-words ya da topic modeling çok daha kolay ve ucuz olur; kalite farkı da neredeyse hissedilmez gibi geliyor. Yazar ve yorum iş parçacığı grafiğini kullanarak da benzer sonuçlar elde edilebilir

    • Maliyetten yazıda bahsedemedim ama birkaç yüz dolar seviyesindeydi, yani bir hobi projesi için bile oldukça erişilebilirdi
      GPU’lar beklediğimden ucuzdu; çoğunlukla sadece sabırsız olduğum için ölçeği büyüttüm :) Tüm küme de sadece birkaç saat çalıştı
      Yaptığınız çalışmaya dair bir bağlantı varsa görmek isterim. İlginç görünüyor, daha fazlasını okumak isterim
    • Yazarın kesinlikle çok yetenekli olduğu belli. HN’de gönderi paylaşmasına rağmen 2018’den beri yorum yapmamış olması da ilginç; ardından bu projeye başlamış
      Finansman ve zaman açısından, muhtemelen bir sonraki işi ya da işyeri arasında ve önceki kariyeri veya girişiminden finansal olarak başarılı olduğu için bunu kendi imkânlarıyla yürütmüş olabilir. GPU kullanımı da çok verimli olduğundan maliyet o kadar büyük olmamış gibidir
    • Daha ucuz embedding’lerle de oldukça iyi sonuçlar elde edilebilir
      Bu tür embedding’lere olasılık kalibrasyonlu SVM gibi klasik makine öğrenmesi uygulayarak sınıflandırma ve kümelemede iyi sonuçlar alınabilir; hız da LLM ince ayarından 100 kattan fazla daha yüksektir
  • Normalde bu demodaki gibi yapmayıp vektörleri normalize edersiniz
    Normalize edilmiş vektörler kullanıldığında Öklid mesafesi, iki vektörün uç noktaları arasındaki mesafeyi ölçer. Buna karşılık kosinüs mesafesi, bir vektörün diğer vektör üzerine izdüşümünün uzunluğunu ölçer

    • Normalizasyonun sorunu, bir serbestlik derecesini kaybetmenizdir. Görselleştirmede bu fiilen bir boyutu kaybetmek gibidir
      Normalize edilmiş 2 boyutlu bir vektör aslında yalnızca 1 boyutlu bir vektördür. 2 boyutlu ilişkileri göstermek istiyorsanız, tekrar 2 serbestlik derecesi elde etmek için 3 boyutlu vektör kullanmanız gerekir
 
ggg213 2024-05-10

Başlık eksik görünüyor.