Skip to content

Untrusted path reports BrokenPipeError instead of the real error when the host throws into a worker #280

Description

@JadenFiotto-Kaufman

An out-of-order access — a common user mistake — is diagnosed correctly on the trusted path and reported as an opaque IPC failure on the untrusted path. Untrusted is the default for real users, so this is the error most people will actually hit.

Reproduction

with model.trace("the " * 64, remote=True):
    lg = model.lm_head.output.save()              # runs LAST
    h0 = model.transformer.h[0].output[0].save()  # runs FIRST -> already passed
path what the user sees
trusted OutOfOrderError: 'model.transformer.h.0.output.i0' was requested but the model already ran past it
untrusted BrokenPipeError: [Errno 32] Broken pipe

The same block in the correct order completes on both paths. Fully reproducible.

Mechanism

From the model actor's log for the untrusted request, the runner does raise the right error:

File "/w/outoforder.py", line 19, in out_of_order
  h0 = m.transformer.h[0].output[0].save()
  value = Mediator.value(location)
  return cls.event(Event.VALUE, location)
  return worker.parent.switch(Pending(event, location, iteration, *rest))
nnsight.intervention.interleaver.OutOfOrderError: 'model.transformer.h.0.output.i0' was requested but the model already ran past it

and then, on the host side:

return driver.pump(connection)
  self.interleave(connection, fn_name, parks, args, kwargs)
  connection.send(("DONE", result))
  self.send_raw(encode(value))
  send_frame(self.sock, data)
  sock.sendall(struct.pack(">Q", len(data)) + data)
BrokenPipeError: [Errno 32] Broken pipe

The host detects the dangling worker and THROWs OutOfOrderError into the runner. The runner raises it and terminates. The host then writes ("DONE", result) to a socket whose peer is already gone, and the resulting BrokenPipeError is what gets reported — the thrown error is never collected.

The misdiagnosis reaches telemetry as well. Two requests, same block, seconds apart:

error_type=OutOfOrderError   ... email=loadtest-trusted@ndif.us     exec_ms=22.12
error_type=BrokenPipeError   ... email=loadtest-untrusted@ndif.us   exec_ms=292.04

so error-rate breakdowns attribute a user error to infrastructure.

Suggested

After THROWing into a worker, the host should treat a subsequent write failure as "the runner died from the error I just threw" and report that error rather than the pipe error — or collect the runner's terminal state before sending DONE. Any error the host itself throws in is already known to it, so it does not need to survive the round trip.

Observed on the Test deployment, ndif 0.8 @ be38d78, nnsight 0.8 @ 3bed88cc.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions