It’s even a problem with per-pixel lighting. The only thing that would truly work is using models where the normals follow the actual curvature more closely. I use Mark Kilgards steep ramp for self shadowing ( a less steep version of it ).
use flatshading (you can use smoothshading but send for every triangle the triangle normal, looks nearly like perpixellighting for the diffuse part, much bether than flatshading after all…
use an approximated shadow-volume with approximates the same way smooth shading does: act per vertex. the demo is wellknown on the nvidiapage for dx existing, the one where you have to add degenerated triangles. with this it should work quite ok…
oh, just one note. why do you get shadow-problems? because you yet shadow the object by itself because of the vertex-lighting AND then you draw a shadow over the shadow… means twice shading… you have to get rid of at least one…