Costruzione di un Pipeline di Dataset di Codice Utilizzando il Metadata di NVIDIA Nemotron-Pretraining-Code-v3 con Streaming, Pandas e Tiktoken
In questo tutorial, lavoriamo con il dataset NVIDIA’s Nemotron-Pretraining-Code-v3 come indice metadati su larga scala per la ricerca di addestramento sul codice. Invece di scaricare l’intero dataset di diverse decine di gigabyte, lo streamiamo, esaminiamo la sua struttura e costruiamo un campione gestibile per l’analisi. Studiamo inoltre i linguaggi, le estensioni dei file, la frequenza dei repository e la profondità della directory, per capire come è organizzato l'indice. Successivamente ricostruiamo gli URL originali da GitHub, tentiamo di ottenere i file sorgente effettivi e stimiamo la scala del token del codice acquisito. Alla fine del flusso di lavoro, creiamo un campione filtrabile riutilizzabile e salviamo le uscite elaborate per esperimenti futuri.
Streaming del Dataset NVIDIA Nemotron-Pretraining-Code-v3 ed Esame della Struttura Schema
Per creare l’ambiente necessario, installiamo le librerie richieste e importiamo gli strumenti utili per il caricamento, l’analisi e la visualizzazione del dataset. Definiamo l’id del dataset NVIDIA Nemotron-Pretraining-Code-v3, scopriamo la configurazione disponibile ed iniziamo lo streaming del set di dati in modalità training. Esaminiamo inoltre la struttura del dataset e stampiamo un record del campione per capire l’organizzazione generale.
!pip -q install -U "datasets>=2.19" huggingface_hub tiktoken pyarrow 2>/dev/null
import os, io, time, itertools, collections, textwrap, math
import pandas as pd
import requests
import matplotlib.pyplot as plt
from datasets import loaddataset, getdatasetconfignames
REPO_ID = "nvidia/Nemotron-Pretraining-Code-v3"
pd.setoption("display.maxcolwidth", 80)
configs = getdatasetconfignames(REPOID)
CONFIG = configs[0]
print(f"Configs available : {configs}")
print(f"Using config : {CONFIG}")
stream = loaddataset(REPOID, CONFIG, split="train", streaming=True)
print("\nFeatures / schema:")
print(stream.features)
print("\nFirst raw record:")
print(next(iter(stream)))
Creare un Campione Mescolato ed Analizzare le Funzionalità del Codice Metadato
Creiamo un campione mescolato del dataset per non affidarci esclusivamente ai primi gruppi di dati. Convertiamo i record in formato DataFrame Pandas e deriviamo funzionalità utili come estensione file, profondità percorso e nome file. Esaminiamo in seguito i linguaggi più comuni, le estensioni di file, i repository più frequenti e le statistiche sulla profondità dei percorsi.
NSAMPLE = 30000
shuffled = stream.shuffle(seed=42, buffersize=20000)
t0 = time.time()
rows = list(itertools.islice(shuffled, N_SAMPLE))
df = pd.DataFrame(rows)
print(f"\nPulled {len(df):,} rows in {time.time()-t0:,.1f}s")
print(df.head(10))
print("\nColumns:", list(df.columns), "| memory:", f"{df.memory_usage(deep=True).sum()/1e6:,.1f} MB")
df["ext"] = df["relpath"].str.extract(r"\.([A-Za-z0-9]+)$")[0].str.lower()
df["depth"] = df["rel_path"].str.count("/")
df["fname"] = df["rel_path"].str.rsplit("/", n=1).str[-1]
print("\n--- Top 15 languages (sample) ---")
langcounts = df["language"].valuecounts()
print(lang_counts.head(15))
print("\n--- Top 15 file extensions (sample) ---")
print(df["ext"].value_counts().head(15))
print("\n--- Most frequent repositories (sample) ---")
print(df["repo"].value_counts().head(10))
print("\n--- Path-depth summary ---")
print(df["depth"].describe())
print(f"\nUnique repos in sample : {df['repo'].nunique():,}")
print(f"Unique languages : {df['language'].nunique():,}")
Visualizzare linguaggi, estensioni di file, profondità delle directory, frequenza dei repository
Utilizziamo diversi grafici per rappresentare i principali modelli rilevati nel nostro set analizzato. Confrontiamo i linguaggi, le estensioni di file, la profondità delle directory e i repository più frequenti del campione. Questi grafici permettono di rendere più facilmente interpretabile il dataset e di individuare velocemente le strutture dominanti all’interno dell’indice dei metadati.
fig, ax = plt.subplots(2, 2, figsize=(14, 9))
lang_counts.head(12).iloc[::-1].plot.barh(ax=ax[0, 0], color="#76b900")
ax[0, 0].settitle("Top 12 languages (sample)"); ax[0, 0].setxlabel("files")
df["ext"].value_counts().head(12).iloc[::-1].plot.barh(ax=ax[0, 1], color="#5b8def")
ax[0, 1].settitle("Top 12 file extensions (sample)"); ax[0, 1].setxlabel("files")
df["depth"].clip(upper=12).plot.hist(bins=range(0, 14), ax=ax[1, 0], color="#f4a261", edgecolor="white")
ax[1, 0].settitle("Directory nesting depth"); ax[1, 0].setxlabel("'/' count in path")
(df["repo"].value_counts().head(10).iloc[::-1].plot.barh(ax=ax[1, 1], color="#9b5de5"))
ax[1, 1].settitle("Most common repos (sample)"); ax[1, 1].setxlabel("files")
plt.tight_layout(); plt.show()
Ricostruzione degli URL GitHub Originali e Recupero dei File Sorgente
Ricostruiamo gli URL originali su GitHub a partire dai metadati relativi al nome del repository, all’ID del commit e al percorso relativo del file. Cerchiamo quindi di recuperare alcuni file sorgente reali da GitHub, gestiamo in modo efficace i file mancanti, cancellati, privati o troppo grandi. Prevediamo inoltre un file recuperato con successo per verificare come il dataset dei metadati si connette al contenuto effettivo.
def rawurl(repo: str, commitid: str, rel_path: str) -> str:
from urllib.parse import quote
return (f"https://raw.githubusercontent.com/{repo}/{commit_id}/"
f"{quote(rel_path)}")
df["rawurl"] = df.apply(lambda r: rawurl(r.repo, r.commitid, r.relpath), axis=1)
print("\nExample reconstructed URLs:")
for u in df["raw_url"].head(5):
print(" ", u)
def fetchcode(url: str, maxbytes: int = 200_000, timeout: int = 10):
try:
resp = requests.get(url, timeout=timeout)
if resp.statuscode == 200 and len(resp.content) <= maxbytes:
return resp.text
return None
except requests.RequestException:
return None
print("\n--- Attempting to fetch a few real files ---")
fetched, attempts = [], 0
for , r in df.sample(frac=1, randomstate=1).iterrows():
if len(fetched) >= 5:
break
attempts += 1
code = fetchcode(r["rawurl"])
status = "OK " if code else "MISS"
print(f"[{status}] {