What pytorch does very well is to play nice python/numpy semantics, especially via broadcasting[0]. There is very little cognitive overhead between a pytorch program and its equivalent python/numpy representation.
What tensorflow does very well is to execute computational graphs on a wide variety of backends. One gpu, many gpus, distributed gpus, servers, mobile, browsers. The recently announced autograph[1] merges the clarity of python/numpy coding style with tensorflow execution engine, offering autograd via compile-time abstract interpretation over all possible traces.
[0] https://docs.scipy.org/doc/numpy/user/basics.broadcasting.ht...
While I am sure pytorch competition contributed to this change, having a graph-based API was a terrible idea whose time would have passed anyway I think. It made some many things complicated for users. As an implementation/optimization strategy, using a graph was a reasonable choice, but to let drive the API as it did was indeed terrible.
It is reassuring to see the TF team addressing the main flaws of the library: removal of graph-based API, and fixing the lack of consistency/plethora of APIs attacking the same problems.