"""Optional GPU workshop. Only the training function requests ZeroGPU.""" import os if os.environ.get('IA_DISABLE_GPU')=='1': def gpu(fn):return fn else: import spaces gpu=spaces.GPU(duration=30) @gpu def train(epochs,rate): import torch epochs=max(10,min(300,int(epochs)));rate=max(.001,min(.2,float(rate))) device='cuda' if torch.cuda.is_available() else 'cpu' g=torch.Generator(device=device).manual_seed(42) x=torch.rand((2048,1),generator=g,device=device)*2-1 y=3*x+2+torch.randn((2048,1),generator=g,device=device)*.1 w=torch.zeros((1,1),device=device,requires_grad=True);b=torch.zeros(1,device=device,requires_grad=True) opt=torch.optim.SGD([w,b],lr=rate);history=[] for i in range(epochs): opt.zero_grad();loss=((x@w+b-y)**2).mean();loss.backward();opt.step() if i==0 or (i+1)%10==0:history.append([i+1,float(loss.detach().cpu())]) hardware=torch.cuda.get_device_name(0) if device=='cuda' else 'CPU' return f'**Matériel réellement utilisé : {hardware}**\n\nRelation apprise : **y ≈ {w.item():.3f} x + {b.item():.3f}**.\n\nCible synthétique : y = 3x + 2 + bruit. L’erreur affichée est celle de l’entraînement ; ce n’est pas une mesure de généralisation.',history